No default constructor for class error

Simple code:

class Thing {
public:
    int num;
    Thing(int num) { 
        this->num = num; 
    }
};

class Stuff {
public:
    Thing thing;  // an instance of thing is declared here but it cannot construct it
    Stuff(Thing thing) {
        this->thing = thing;
    }
};

int main() {
    Thing thing = Thing(5);
    Stuff stuff = Stuff(thing);
}

      

So here I am trying to figure out how I should accept a new Thing instance in the Stuff constructor without pointing to it, as I want Stuff to keep its own copy. Of course, I cannot declare a thing like mine because it is trying to initialize it.

How can I get around this problem of assigning a new copy of an object to a class variable through my constructor?

The exact error:

In constructor 'Stuff::Stuff(Thing)':
error: no matching function for call to 'Thing::Thing()'
  Stuff(Thing thing){ this->thing = thing; }

candidate expects 1 argument, 0 provided

      

+3


source to share


3 answers


The problem is here:

Stuff(Thing thing) {
    this->thing = thing;
}

      

By the time you enter the body of the constructor, the compiler has already initialized the data members of the object. But it can't initialize thing

because it doesn't have a default constructor.



The solution is to tell the compiler how to initialize it using an initialization list.

Stuff(Thing thing) : thing(thing) {
    // Nothing left to do.
}

      

This is less typical, cleaner code, and more efficient. (More efficient, because if the variable is going to be initialized anyway, then why initialize it with an unwanted value to just assign another as fast as you can? Of course, since your current code doesn't even compile, the "more efficient" is somewhat dubious expression here.)

+11


source


Initialize an element of an element in Stuff using an initializer list:



class Stuff {
public:
    Thing thing;  // an instance of thing is declared here but it cannot construct it
    Stuff(Thing thing): thing(thing) { }
};

      

+2


source


The only constructor Thing

takes a parameter int

.

Thus, when you state:

Thing thing;

      

Without arguments, how does he know what should be num

?

As the bug says, 1 is expected, but no one provided. You either need to add a default constructor:

Thing::Thing(void) : num(0){};

      

or change the argument:

Thing::Thing(int num=0)

      

In both cases I used 0

, but that should be whatever you think num

should be the "default" when nothing is specified.

Without it, it Stuff

Thing

should matter to initialize it; this is maintained via the initialization list, which you neglected to use in Thing::Thing

(see above), and as a side note, yours is this->num

not needed, num

is sufficient.

Stuff::Stuff(Thing inThing) : thing(inThing){};

      

+1


source







All Articles