0

I have a class with its constructor having a parameter. Now I had to declare class A object. But I need to call the constructor later. But if I do that, I get the error.

e.g.

class A{
        public:
        int a;
        A(int x){
                a=x;
        }
};
int main(){
        A a;
        a=A(3);
}

Error

temp.cpp: In function ‘int main()’:
temp.cpp:10:4: error: no matching function for call to ‘A::A()’
temp.cpp:10:4: note: candidates are:
temp.cpp:5:2: note: A::A(int)
temp.cpp:5:2: note:   candidate expects 1 argument, 0 provided
temp.cpp:3:7: note: A::A(const A&)
temp.cpp:3:7: note:   candidate expects 1 argument, 0 provided
8
  • 1
    Why can't you just initialize with a dummy integer and overwrite it later with the real value? Commented Jul 15, 2014 at 10:43
  • 5
    This is not possible. The constructor is used for construction. Not for calling later. Commented Jul 15, 2014 at 10:44
  • You can't do a=A(3) as default visibility in C++ classes is private, thus uncallable outside the class. As for calling later,if for some reason you need object to be created at certain point of time (order on stack?) and initialized later (dependant on other objects?) you may move initializing code out of a constructor to some init member function. Commented Jul 15, 2014 at 10:46
  • Provide a default constructor such as A() {a=0;} and a copy constructor A(const A &r) {a = r.a;}. Best of luck. Commented Jul 15, 2014 at 10:46
  • 3
    @LukaszDaniluk "You can't do a=A(3) as default visibility in C++ classes is private" does not describe this situation. It is perfectly correct to call A(3), which will create a separate instance of the class, which then can be copied to a variable of this class if the class has an assignment operator. Commented Jul 15, 2014 at 10:49

5 Answers 5

2

The only good solution here is to avoid this situation arising in the first place.

The situation typically arises when you have something on the general order of having to create an object where its initial value depends on some condition, so conceptually what you want is something on this general order:

if (xyz)
    A a(123);
else
    A a(456);

// code that uses A goes here

The problem in this case is that in this case, A goes out of scope before you can use it. The cure is typically to divide this code up into two functions, so you end up with something like this:

if (xyz)
    code_that_uses_A(123);
else
    code_that_uses_A(456);

Although I certainly prefer to avoid it, there is another possibility that can be workable: a wrapper object that keeps track of whether the object it contains has been initialized or not. For example, it can contain a pointer to the actual object. This is initialized to a null pointer. When you initialize the object it contains, you allocate a contained object. Depending on what you want, attempting to re-initialize the container object could throw or it could just assign a new value to the contained object.

Of these two, the former is nearly always preferable. It tends to clean up the code and give each individual piece of code a single, clear responsibility. The latter can work, but generally requires quite a bit of work to get the wrapper object present a clean interface. Although I'd usually consider it a lesser concern, such a wrapper typically adds substantial overhead to using the wrapped object.

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

1 Comment

Why not int i; if (xyz) i=123; else i=456; A a(i)? But if the if statement is going to be that simple, you might as well use the ternary operator: A a(xyz ? 123 : 456)
2

The very point of the constructor with parameter is to ensure that no object of the class may exist without a initialised. You cannot "call constructor later". You may add another constructor though, without parameters.

1 Comment

Exactly, the class member functions maintain the class invariants, a constructor ensures a new object is well defined.
0

Whenever you define an object. constructors get automatically called. What you may have as below:

class A{
  int a;
 public:
  A(int x = 0){
    a=x;
  }
  A(const A&arg) {a = arg.a;}
  A& operator =(const A&arg) {a = arg.a;return *this;}
};
int main(){
  A a;
  a=A(3);
  return 0;
}

Constructors may also have default arguments, so A a; might actually be implemented as like a call to constructor A(0) See Default parameters with C++ constructors

Comments

0

The issue here is that you have defined a constructor for A class which takes int as an argument. As you have defined your own constructor, compiler will not define default constructor for your class.

A(int x)
{
        a=x;
}

When you call:

A a;

This will look for a constructor for A class which does not take any argument. But that is not present. Thus the compilation error is coming.

Comments

-1

You should initialize any instance of a class. There is no way to have a "dummy" variable in no well-defined state, unless your class has a constructor without arguments.

Or, add a constructor with no arguments.

Note that assignment in a = A(3) calls an assignment operator on a.

4 Comments

No, a = A(3) calls the assignment operator
Right. Changing my answer.
The whole point of constructors for a class, is SO every object created maintains the class invariants and is thus in some defined state.
Care to explain why downvoted? I said the same: that no object can be created without constructor in no well-defined state. What's wrong with it? Of course a constructor with no arguments (default constructor) should also leave the object in a well-defined state. Please explain what's wrong with my answer.

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.