How to remind a param passed to the base class constructor? - c++

Having a member and pass the same to the base class works if:
DerrivedClass::DerrivedClass(SomeParamType* p)
: BaseClass(p),
derrivedClassMember(p),
{
...
}
... but how to share without passing it as param to the DerrivedClass constructor? Is this valid? Or is the derrivedClassMember not initialized at this time?
DerrivedClass::DerrivedClass()
: BaseClass(derrivedClassMember),
derrivedClassMember(new SomeParamType()),
{
...
}
I'm not able to change the base class implementation.

In C++11 you could use a delegating constructor:
class Derived : public Base {
public:
Derived() : Derived(new SomeParamType()) {}
...
private:
Derived(SomeParamType* p) : Base(p), derivedMember(p) {}
};
As a side note, I know this is probably just an example but you shouldn't create unmanaged objects on the heap like this in a constructor: if the Base constructor throws then you're in for a memory leak. Prefer smart pointers whenever possible.

I'm cringing as I write this, but....
DerrivedClass::DerrivedClass(SomeParamType* p = new SomeParamType())
: BaseClass(p),
derrivedClassMember(p)
{
}
I need to go shower now. Regardless, in deference to your question, yes, your base constructor should be executed before your members are initialized. Members have to be initialized in their top-down order, starting with the base members in its constructor and working out.
Note: I'd have to dust off my standard copy to find where this is specified, but I'm fairly sure its in there, as lint loves to tell you about out-of-order initialization warnings and their non-compliance.

It is not initialialized at that time. The baseclass constructor is called before the derrivedClassMember is initialized. That's because the derived members or the constructor of the derived class may depend on members of the baseclass.

To sum up the answers given up to now, and add a bit more, there are a few possible solutions.
1 If your base class has an accessor for the member, its fairly easy:
DerrivedClass::DerrivedClass()
: BaseClass(new SomeParamType()),
derrivedClassMember(getBaseClassMember()),
{
...
}
2 in C++11, use a delegating constructor, calling the original constructor you posted:
DerrivedClass::DerrivedClass()
: DerrivedClass(new SomeParamType())
{}
3 in C++03, use a default argument (which is ugly):
DerrivedClass::DerrivedClass(SomeParamType* p = new SomeParamType())
: BaseClass(p),
derrivedClassMember(p),
{
...
}
4 Another workaround, to get rid of the constructor default argument in C++03, would be to use multiple inheritance to get the derivedclassMember initialized before the base class:
struct DerivedClassInitializationWorkaround {
SomeParamType* derivedClassMember:
DerivedClassInitializationWorkaround(SomeParamType* param)
: derivedClassMember(param) {}
};
class DerivedClass : private DerivedClassInitializationWorkaround, //this has to go first!
public BaseClass {
public:
DerivedClass::DerivedClass()
: DerivedClassInitializationWorkaround(new SomeParamType())
, BaseClass(derivedClassMember)
{}
};
The initialization of base classes occurs in the order of their declaration, so if you derive from DerivedClassInitializationWorkaround, the derivedClassMember it contains gets initialized first.
In any cases, your code is not exception safe. You should not store owning pointers as raw pointers but use smart pointers. Since you can't change the base class, you will have to determine if it takes ownership of the object (i.e. if it destroys the object you pass to its constructor.
If the base class object takes ownership, you are more or less stuck with the existing solutions, except that your derived class should store a reference instead of the pointer, because the base class object and therfore the SomeParamType object will outlive the derived class' object.
If the base class does not take ownership, you should store a unique_ptr:
class DerivedClass : public BaseClass {
unique_ptr<SomeParamType> derivedClassMember;
DerivedClass::DerivedClass(unique_ptr<SomeParamType> param)
: BaseClass(param.get())
, derivedClassMember(move(param))
{}
public:
DerivedClass::DerivedClass()
: DerivedClass(make_unique<SomeParamType>)
{}
};

Short answer is no, it is not valid.
Here's a good answer to your question:
Order of calling base class constructor from derived class initialization list

Related

Is it possible to run member initializers before base-class constructor?

Normally one can change the order in which member initializers run by changing the order in which the members are declared in the class. However, is there a way to get the base class initializer/constructor to not run first?
This is a minimal sketch of my problem:
class SpecialA : public A {
public:
explicit SpecialA(Arg* arg)
: member(expensiveFunction(arg))
, A(member) // <-- This will run first but I don't want it to
{}
private:
T member;
}
No, it is not possible. Class initialization is always like that: base class, members, this class constructor.
The reason for this is simple - since you can reference your members in this class constructor, you have to construct members before you call your constructor. Since you can reference your base class members from your members, you have to have them constructed before this class members.
Is it possible to run member initializers before base-class constructor?
Not as such.
That said, here are a few solutions:
1: move the member to an artificial base:
template<typename T>
class InitializerBase {
protected:
InitializerBase(T&& value) : member(std::move(value)) {}
T member;
};
class SpecialA: public InitializerBase<T>, public A {
public:
SpecialA(Arg *arg) : InitializerBase<T>(expensiveFunction(arg)): A{}
{
}
};
(Probably) the best solution would look like this:
2: use dependency injection for the fully constructed value (this is safest, best design and unless your code has bigger problems, most efficient implementation):
class SpecialA : public A {
public:
explicit SpecialA(T fully_computed_value)
: A(fully_computed_value)
, member(std::move(fully_computed_value)) // no heavy computations performed
{}
private:
T member;
}
Construction:
auto &a = SpecialA(expensiveFunction(arg));
This is the best solution because if expensiveFunction throws, you do not even start constructing the resulting object (the application doesn't have to release the resources for the half-constructed SpecialA).
Edit:That said, if you want to hide the use of the expensive function, the canonical solution to that (canonical because it is reusable, minimalistic and still respects good design) is to add a factory function:
SpecialA make_special(Arg *arg)
{
auto result = expensiveFunction(arg);
// extra steps for creation should go here (validation of the result for example)
return SpecialA( std::move(result) );
}
client code:
auto specialA = make_special(arg); // simplistic to call (almost as simple
// as calling the constructor directly);
// hides the use of the expensive function
// and provides max. reusability (if you
// need to construct a SpecialA without
// calling the expensive function, you
// can (by obtaining the constructor argument
// for SpecialA in a different way)
Just realized how to solve the problem:
class SpecialA : public A {
public:
explicit SpecialA(Arg* arg) : SpecialA(arg, expensiveFunction(arg)) {}
private:
SpecialA(Arg* arg, T&& member) : A(member) , member(member) {};
T member;
}
Base class constructor must be called first.You cannot go any other way around but you can device a way to not make class A base class and call first whatever you want.
The base class is always fully constructed first. There is no way round this.
One alternative would be to break the inheritance and move the the base class to a member variable of the child class.
The order of member initialisation is then the order they appear in the class declaration.
But relying on this can make your code brittle, so do bear that in mind. Putting a suitable comment in the class declaration might not sufficiently discourage an enthusiastic refactorer.
The order of member initializers in the list is irrelevant: the actual
order of initialization is as follows:
1) If the constructor is for
the most-derived class, virtual base classes are initialized in the
order in which they appear in depth-first left-to-right traversal of
the base class declarations (left-to-right refers to the appearance in
base-specifier lists)
2) Then, direct base classes are initialized in
left-to-right order as they appear in this class's base-specifier list
3) Then, non-static data members are initialized in order of
declaration in the class definition.
4) Finally, the body of the
constructor is executed
Source: http://en.cppreference.com/w/cpp/language/initializer_list
in your case it looks like it would be more correct to invert the ownership of the item:
struct A
{
protected:
A(T expensive_object) : _expensive_object(std::move(expensive_object)) {}
protected:
T& access_expensive_object() {
return _expensive_object;
}
private:
T _expensive_object;
};
class SpecialA : public A {
public:
explicit SpecialA(Arg* arg)
: A(expensiveFunction(arg))
{}
void use_object() {
auto& o = expensive_object();
do_something_with(o);
}
};
Also you can use a reserved optional parameter as a placeholder:
class SpecialA : public A {
public:
SpecialA(Arg* arg, std::optional<T> reserved = {}) :
A(reserved = expensiveFunction(arg)),
member(reserved)
{}
private:
T member;
}
It can be better than delegating constructors because it bloats code less when there is a lot of parameters. Also there may be more overhead with delegating constructors (please, correct me if I'm wrong).

Initializing variables in a class hierarchy

I got assigned the task to clean up a class hierarchy, but I'm stuck in a bit of a rut. I'm now left with something that roughly looks like this:
class Base
{
Base() = 0;
function1();
...
function5();
protected:
int variable1_;
...
int variable10_;
};
class DerivedOne
: public Base
{
DerivedOne() = 0;
function6();
...
function10();
protected:
int variable11_;
...
int variable20_;
};
class DerivedTwo
: public DerivedOne
{
DerivedTwo()
: DerivedOne()
{
... Fill variable1_ to variable25_ with data read from file ...
variable1_ = ...
}
function11();
...
function15();
private:
int variable21_;
...
int variable25_;
};
So 25 variable are assigned their values in DerivedTwo, making it easy to make a mistake. When another class inherits from DerivedOne, it's almost certain that that person will forget to initialize one of the variables.
I've been playing around with different ways of designing this hierarchy, but nothing really feels right.
I understand it's difficult to say something concrete without knowing what these classes actually do, but I would be interested in knowing if there is something fundamental wrong with this design, or if I have overlooked some elegant way of initializing all the variables.
The principle in derivation is that base object is constructed first, and the derived afterwards. This requires the Base and DerivedOne constructor to produce a valid object on its own.
When constructing DerivedTwo, your code makes this clear:
DerivedTwo()
: DerivedOne() // First the base object constructor is called, before anything else
{
// then remaining initialisation, after DerivedOne() was created
}
So each class should at least initialise its own variables to an initial valid state that its own functions can handle in a consistent manner.
Base() : variable1_(/*default value here*/), variable10_(/*default value here*/) {}
Base(int v1, int v10) : variable1_(v1), variable10_(v10) {} // for convenience
One derived class could overwrite variables of its base class afterwards. It would of course be safer and more elegant to use getters/setters, but its ok.
If you adopt this design, if one subderived class forgets to initialise a variable one of its parents, this should not lead to a catastrophee because at least the base object is initialised in a decent manner.
Now the problem is that you also initiate your DerivedTwo by reading a file. Remember, first Base is created, then DerivedOne, and then only DerivedTwo reads the values. What happen when the file cannot be read or is unconsistent ? You might end up having an inconsistent object, unless your throw an exception. So you have to manage this and make sure that DerivedTwo is in a stable state:
DerivedTwo()
: DerivedOne() // First the base object constructor is called
{
// then initialise all own members to a consitent state
// then try to read the file and manage potential errors
}
Each class should be responsible for initializing its own data members. As you identified, it is dangerous for Base to assume that DerivedX will initialize its data members. So...
Base should initialize variable1_ ... variable10_
DerivedOne should initialize variable11_ ... variable20_
DerivedTwo should initialize variable21_ ... variable25_
...and so on.
Of course, this doesn't address the question of why the classes are laid out in such a fashion...

Constructor inheritance problems c

If my base class's constructor takes parameters, how do I create a class that inherits from it, and executes the base class's constructor using the derived class's constructor?
For example, assuming my base class's instructor takes an integer, and does a cool trick with it, how would I make it so all classes that inherit from it can do the same
Pseudo-code
baseClass instance(99); //does an awesome trick, nice
derivedClass instance(99); //<-- should do the same as above
As I have it now, I have my base class's constructor defined, but for the derived class, I left its constructor blank, since I want it to do exactly what the base constructor does, and nothing more. But, this gave me an error along the lines of: no matching function call to the 'baseClass()', candidates are: baseClass(int), candidate expects 1 argument, 0 provided
Do I have to make the base class's constructor virtual or something?
This is easy in the current C++ standard, but it still requires some action on your part:
struct baseClass
{
explicit baseClass(int);
};
struct derivedClass : baseClass
{
using baseClass::baseClass; // inherit *all* of baseClass' constructors
};
In the previous standard, C++03, you have to implement the constructor in the derived type and call the base class's one in the initialization list:
struct derivedClass : baseClass
{
explicit derivedClass(int i) : baseClass(i) {}
};
Note: I use struct here to save typing: default member access and inheritance is public.
The idea is that derivedClass will need to call baseClass constructor anyway, since it needs to to complete its construction. The error you get is due to the fact that, without calling a the base constructor explicitly, the compiler is trying to call the default one.
However, in your case, it does not exist, since you already defined a constructor that takes an int. To do what you want, a solution could be to do this:
class derivedClass : baseClass {
public:
derivedClass(int x) : baseClass(x) {}
};

Can we avoid the default constructor in this case?

Observation: The constructor of ClassMain needs to call Init before it can constructor a member variable a. Since the ClassA has no default constructor, the code doesn't compile.
ClassA
{
public:
// This class has no default constructor
ClassA(...){}
};
class ClassMain
{
public:
ClassMain(...) {
Init(...);
a = ClassA(...); // error: ClassA has no default constructor
// a has to been constructed after the Init is called!
}
ClassMain(...) {
Init(...);
call other functions
a = ClassA(...);
}
private:
// initialize environment
void Init(...) {}
private:
ClassA a;
};
Question> The simple solution is to provide a default constructor for ClassA. However, I would like to know whether there is a better solution to address the issue above?
The better solution is not to require an Init function at all. You're trying to reinvent constructors, and breaking their design in the process.
If Init does too much work for a constructor, then do it outside and pass the resulting resources into ClassMain as a constructor argument; notice how you're already doing all the work in the constructor's scope anyway, thereby not gaining anything appreciable over proper initialisation.
Of course, if you must perform a ton of work before initialising a, and you cannot pass in a ClassA& from the outside and initialise from that, then you're simply going to have to have a be an indirect member.
There is one nasty workaround you could use: have Init actually be a base constructor...
The obvious solution is to call Init() from the initializer list of an early member or a base class. Once this subobject is constructed its results can be passed to the constructors of other subobjects. For example, when defining stream classes I typically privately inherit from a virtual base containing the stream buffer:
struct somebuf_base {
somebuf sbuf;
// ...
};
class somestream
: private virtual somebuf_base
, public std::ostream
{
public:
somestream(someargs)
: somebuf_base(someargs)
, std::ostream(&this->sbuf) {
}
// ...
};
Since base classes are constructed in the order they appear but virtual bases before non-virtual bases, the base class containing the sbuf member is constructed first. Its constructor replaces your Init() function.
When using C++ as of the 2011 revision, you might also use forwarding constructors to share logic between multiple constructors.
It's easier to take a pointer to ClassA; So, you can instantiate it whenever you want.(after the init())
If you used a pointer, don't forget to implement the virtual destructor and release the allocated memory for the ClassA *a
If you absolutely must call some function at the start of your constructor, and can't put that setup into some base class or early-constructed member, you could use this ugly trick:
ClassMain::ClassMain(int main_param)
: a( (Init(init_arg), class_a_arg1), class_a_arg2 )
{
}
In this case: No, we cannot avoid that.
The reason is that when calling Init or any other member function you are guaranteed by the language that the object you are in exists. As a is a member of ClassMain it must be constructed before any function in ClassMain can be called.
The only chance that you have here is to refactor the code.

Why does a purely virtual/abstract class require a constructor, in particular for protected const member variables?

I have a purely virtual class defined as such:
class BaseClass {
protected:
const int var;
public:
void somefun() = 0; // what I mean by a purely virtual class
// stuff...
};
If I don't add a constructor defined as such:
BaseClass(const int & VAR) : var(VAR) {};
that I would have to subsequently use in ever derived class, my derived class can't initialize the const variable var to whichever value it wants to. Now I actually understand what's going on here. Before constructing a derived class, a constructor of the base class is called, at which point const member variables must be initialized. My question is not a "how do I make my code work" kind of question, that's already been done. My question is about why the compiler thinks it's necessary. For a purely virtual class, shouldn't I be allowed to write something like:
class DerivedClass : BaseClass {
public:
DerivedClass() : var(SOME_VALUE) {};
}
If the compiler knows that a call to a BaseClass constructor will necessarily be followed by a call to some derived class constructror (since an object of abstract type can never be instantiated) shouldn't it give us a bit more leeway?
Is this all a consequence of how C++ chooses to get around the Diamond problem? Even if that was the case, shouldn't the compiler at least somehow allow for the possibility that const member variable of purely virtual functions will be defined in derived classes? Is that too complicated or does that mess with the C++ solution to the Diamond problem?
Thanks for the help everyone.
It's not "purely virtual" (whatever you mean by that) - it contains a data member.
Class members can only be initialised by the initialiser list of a constructor of that class, not of a derived class. That's how object initialisation is specified: all members that are initialised, are initialised before the constructor body begins.
Constant objects must be initialised, since they can't be assigned a value later.
Therefore, a class with a constant data member must initialise it in each constructor.
For a purely virtual class, shouldn't I be allowed to write something
like
No, but you can(and in this case should) write something like this:
class DerivedClass : BaseClass {
public:
DerivedClass() : BaseClass(SOME_VALUE) {};
};
The construction of an object occurs in a specific order. The base class must be fully constructed before the constructor of a derived class is run, so that the derived constructor is working with a fully formed and valid base object. If the initialization of base member variables were put off until the construction of the derived class, this invariant would be broken.