Construction of object with non-default constructo

2019-09-16 03:03发布

问题:

Iam new to C++ and below mentioned is the summary of the problem. Bar's constructor needs to explicitly call foo's constructor and the argument to foo's constructor has to be an object to baz, which has a default constructor. Iam not allowed to use new operator(dynamic allocation) to achieve this. I tried the below code, but C++ compiler gives me compilation errors (listed below). Can somebody please explain me what's going wrong in this code? Any help is really appreciated.

//Constructor.cpp
#include <iostream>
using namespace std;    // two of two, yay!

class baz {
public:
baz() { };
};

class Foo {
public:
Foo(baz y) { }
};

class Bar  {
public:
Foo x;
baz y;
Bar() : Foo(y) { };
};

int main() {
Bar b;
}

Syntax Error on compiling.
--------------------------
constructor.cpp: In constructor `Bar::Bar()':
constructor.cpp:19: error: type `Foo' is not a direct base of `Bar' 
constructor.cpp:19: error: no matching function for call to `Foo::Foo()'
constructor.cpp:9: note: candidates are: Foo::Foo(const Foo&)
constructor.cpp:11: note:                 Foo::Foo(baz)

回答1:

Bar() : Foo(y) { };

What are you doing here? Foo is not a member of Bar. It's a type. x is a member of type Foo.

But even if you write x(y), there is a problem in the order of initialization. As x is depending on y, so y must be initialized before x. So declare y before x to ensure the correct initialization!

I would suggest this change:

class Bar  
{
   public:
      baz y;
      Foo x; //NOTE : x declared after y, as x is depending on y!
      Bar() : x(y) {}
};


回答2:

Bar isn't derived from Foo, it has a member called x of type Foo so x must appear in the mem-initializer-list.

Bar : x(y) {}

For this to be valid, though, the declaration of y must appear before the declaration of x in the definition of class Bar as the order of initialization of members of a class always occurs in the order in which the member declarations appear in the definition of the class and, if you are initializing x from y you will want y to be initialized before x.

Also, note you are missing a semicolon after the definition of class baz.