6

I'm learning C++.

I want to declare a variable without creating an instance of it.

MyClass variable;

// More code

int main(int argc, char **argv)
{
   // More code
   variable = MyClass(0);

   // More code
}

If I do that, and MyClass only has a constructor declared MyClass::MyClass(int value) it fails.

I need to make it global because I'm going to use it on a CallBack function and I can pass that variable as a parameter.

And also, I don't want to create an instance of the class when I declare the variable and then, another instance when I use the constructor. I think I'm wasting resources and CPU time.

Is it possible to declare a variable without instance it?

4
  • 1
    Sounds like an XY problem. Why not just declare the object when you are ready to construct it? Commented Jul 15, 2019 at 19:43
  • Because I need it on a CallBack function and I can pass that variable as a parameter. Commented Jul 15, 2019 at 19:43
  • 4
    If your class is not copyable and not movable, than you can not copy or move it. May be you need two-step initialization with dreaded init function? Or maybe std::optional could be a... hm... option. Commented Jul 15, 2019 at 19:46
  • Maybe I can do MyClass* variable = NULL. Commented Jul 15, 2019 at 19:47

5 Answers 5

6

Use a pointer to delay instantiation. Prefer smart pointers to raw pointers so you don't have to worry about manual memory management.

#include <memory>

std::shared_ptr<MyClass> variable;

// More code

int main(int argc, char **argv)
{
   // More code
   variable = std::make_shared<MyClass>(0);

   // More code
}

Whether you use std::unique_ptr or std::shared_ptr depends on what you plan to do with the pointer.

Sign up to request clarification or add additional context in comments.

1 Comment

How can we do this with regular pointers ?
4

You can use a std::optional for this:

#include <optional>

std::optional<MyClass> variable; // not initialized

int main() {
    if (variable) {
        // enters this if only when initialized
    }

    variable = MyClass(0);

    // Access the contained value:
    MyClass value = *variable;
    int member = variable->member;
}

The std::optional type is available in C++17. If your project is constrained to an older version, you can always use a polyfill

Comments

1

I am not sure, but it seems like you have created a constructor like :

MyClass(int v) : value(v) {}

and not written the default constructor, which may look like :

MyClass() {}

Because of this, the compiler cannot find the constructor to instantiate a MyClass object when you write:

MyClass variable;

In short, you have to explicitly write the default constructor when you have written other constructors but also want to use the default one.

And your question is a bit vague, when you declare a variable of a class like above, you are indeed creating an instance of it. Even when doing

variable = MyClass(0);

you are creating a temporary object of MyClass and then using the assignment operator to assign it to the variable object.

2 Comments

Yes, I don't want to create an instance when I declare it and then another instance when I use the constructor.
Yes, I think that a smart pointer is a solution then, as suggested by John.
1

You could just initialise the variable with some temporary value with the existing constructor when you declare it. Ideally with a value you could easily identify when debugging.

MyClass variable(-1);

Although then it would probably make more sense to just add a default constructor that does that.

Comments

0

I want to declare a variable without creating an instance of it.

In your code you have:

MyClass variable; 

Declared in the global namespace. Here variable is still an instance of MyClass; it just has different storage, linkage and lifetime than if it was within a function.

As to having it declared in a global namespace and initializing it afterwards here is what I have tried this and it seems to work for me. I'm not sure if this is what you are after, but I think this may work for you.

#include <iostream>

class MyClass {
private:
    int value_;

public:
    MyClass() : value_{ 0 } {}
    explicit MyClass(int value) : value_{ value } {}

    MyClass& operator()(int value) {
        value_ = value;
        return *this;
    }

    int value() const { return value_; }
};

MyClass myClass;

int main() {
    std::cout << myClass.value() << '\n';

    myClass = MyClass(2) << '\n';
    std::cout << myClass.value() << '\n';

    myClass(5);
    std::cout << myClass.value() << '\n';

    std::cout << myClass(8).value() << '\n';        

    return 0;
}

Output

0
2
5
8

Let me know what you think.

1 Comment

Thanks for your answer. I don't want to create an instance of the class when I declare the variable and then, another instance when I use the constructor. I think I'm wasting resources and CPU time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.