Reputation: 4419
I would like to include a Composed
object in my Base
class, and have different derived classes have different configurations of it. However the Composed
class requires parameter in constructor, and I don't have control over its architecture.
The compiler is reporting an error because the parameter for Composed
should be passed at the initialization of Base
class. But I only want it to be initialized in derived classes. What should I do in this case?
class Base{
public:
Base(); //Error
protected:
Composed comp;
};
class Composed{
public:
Composed(int id):id(id);
private:
int id;
};
class Derived_1:public Base{
public:
Derived():comp(1234){};
};
class Derived_2:public Base{
public:
Derived():comp(2345){};
};
Upvotes: 1
Views: 245
Reputation: 1633
Imagine you constructed a Base
object. How would it know what parameter to pass to comp
's constructor? The Base
class is fundamentally flawed, that's why you have an error. It needs to know how to construct it's Composed
member object.
You can add a default constructor for Composed
, and then modify this object in Derived_1
and Derived_2
. Alternatively, as others suggested, you can make Base
's constructor take the parameters to construct comp
. This sounds preferable to me, but it depends on your use case.
Remember that when you are constructing Derived_1
or Derived_2
, the Base
class is the first thing that is created, before other member variables.
Upvotes: 2
Reputation: 2530
There are a few options. The most straightforward is to pass the objects required to build Comp to the Base class constructor.
class Base{
public:
Base(int id):comp(id){}
protected:
Composed comp;
};
class Derived_1:public Base{
public:
Derived():Base(1234){}
};
class Derived_2:public Base{
public:
Derived():Base(2345){}
};
Another possibility is not to include Comp in the base class. Put it in each derived class. You can add a pure virtual function to the Base class that returns Comp (or its address).
One more option is to store a pointer to Comp (perhaps a unique_ptr) and allocate it in the derived classes.
Upvotes: 1
Reputation: 3375
You'll have to pass that parameter up to Base, and then hand it down to comp:
class Composed{
public:
Composed(int id):id(id);
private:
int id;
};
class Base{
public:
Base(int id):comp(id){}
protected:
Composed comp;
};
class Derived_1:public Base{
public:
Derived():Base(1234){};
};
class Derived_2:public Base{
public:
Derived():Base(2345){};
};
Upvotes: 4