I'm deriving a class which is available from a C++ library, and the constructor of my subclass will only work properly when I execute some code before the base class constructor gets called. (Yes, I know, bad design, but I cannot influence how the library which I'm using works.)
If the base class constructor takes arguments, doing this is actually quite simple:
struct A {
A(bool a) { printf("A::A()\n"); }
};
bool inject(bool a) { printf("inject()\n"); return a; }
struct B : public A {
B(bool a) : A(inject(a)) { printf("B::B()\n"); }
};
Now, when I construct an instance of B, inject() gets called before A::A(). But is there a way to do this when the base class ctor has no arguments?
You have a case of "Base from member initialization".
A solution is there.
Hacky injection code aside, I think the reasonable way to do this is to do the "has a" instead of "is a" pattern: Simply have an instance of the library class inside of your own class. That way you can control allocation and deallocation order to your heart's content.
Your solution for the one parameter constructor doesn;t really seem useful in the sense that it still cannot access the class being constructed (as it doesn't happen yet) and it is unclear how anything useful can be done with this hacky form (except perhaps setting global scope values which affect the base ctor).
Stephan's proposed solution would look something like this:
struct A {
A() { printf("A::A()\n"); }
};
struct Injector {
Injector() { printf("inject()\n"); }
}
struct B : public A,private Injector {
B() : Injector(), A() { printf("B::B()\n"); }
};
This is an okay solution but seems a little clumsy to me.
Another possible solution is using static class function in place of the constructor for B which run the inject before returning an instantiated object created with a private constructor but it seems from your question that this don't suit your context.
Why you can't add one more layer ?
struct A {
A(bool a) { printf("A::A()\n"); }
A();
};
struct A_Wrap : public A {
A_Wrap(bool ) : A() { } ;
};
bool inject(bool a) { printf("inject()\n"); return a; }
struct B : public A_Wrap {
B(bool a) : A_Wrap(inject(a)) { printf("B::B()\n"); }
};
Related
I've got a base class that has a virtual function. I want to call that class during the construction because I want the function called for each of the derived classes. I know I can't call a virtual function during construction, but I can't think of an elegant (i.e., avoid repeating code) solution.
What are some work arounds to calling a virtual function during construction?
The reason I want to avoid this is because I don't want to have to create constructors that just call the base class.
class A {
public:
A() {
read();
}
// This never needs to be called
virtual void read() = 0;
}
class B:A {
public:
B():A() { };
read() { /*Do something special for B here.*/ }
}
class C:A {
public:
C():A() { };
read() { /*Do something special for C here.*/ }
}
PS: The Python way of doing this is simply to raise NotImplementedError in A::read(). I'm returning to C++ and I'm more rusty than I thought.
The FAQ perspective.
This is a Frequently Asked Question.
See the C++ FAQ item titled “Okay, but is there a way to simulate that behavior as if dynamic binding worked on the this object within my base class's constructor?”.
It’s very often a good idea to check the FAQ (and generally, googling or altavista’ing) before asking.
The question as “Derived class specific base initialization”.
To be clear, while the literal question above is
“What are some work arounds to calling a virtual function during construction?”
it is evident that what’s meant is
“How can a base class B be designed so that each derived class can specify part of what goes on during B construction?”
A major example is where C style GUI functionality is wrapped by C++ classes. Then a general Widget constructor might need to instantiate an API-level widget which, depending on the most derived class, should be a button widget or a listbox widget or whatever. So the most derived class must somehow influence what goes on up in Widget’s constructor.
In other words, we’re talking about derived class specific base construction.
Marshall Cline called that “Dynamic Binding During Construction”, and it’s problematic in C++ because in C++ the dynamic type of an object during class T construction and destruction, is T. This helps with type safety, in that a virtual member function is not called on a derived class sub-object before that sub-object has been initialized, or its initialization has started. But a major cost is that DBDI (apparently) can’t be done in a way that is both simple and safe.
Where the derived class specific init can be performed.
In the question the derived class specific action is called read. Here I call it derived_action. There are 3 main possibilities for where the derived_action is invoked:
Invoked by instantiation code, called two-phase construction.
This essentially implies the possibility of having a mostly unusuable not fully initialized object at hand, a zombie object. However, with C++11 move semantics that has become more common and accepted (and anyway it can be mitigated to some extent by using factories). A main problem is that during the second phase of construction the ordinary C++ protection against virtual calls on uninitialized sub-objects, due to dynamic type changes during construction, is not present.
Invoked by Derived constructor.
For example, derived_action can be invoked as an argument expression for the Base constructor. A not totally uncommon technique is to use a class template to generate most derived classes that e.g. supply calls of derived_action.
Invoked by Base constructor.
This implies that knowledge of derived_action must be passed up to the constructor, dynamically or statically. A nice way is to use a defaulted constructor argument. This leads to the notion of a parallel class hierarchy, a hierarchy of derived class actions.
This list is in order of increasing sophistication and type safety, and also, to the best of my knowledge, reflects the historical use of the various techniques.
E.g. in Microsoft’s MFC and Borland’s ObjectWindows GUI early 1990’ libraries two-phase construction was common, and that kind of design is now, as of 2014, regarded as very ungood.
This is the factory method approach, putting the factory into the base class:
class A {
public:
virtual void read() = 0;
template<class X> static X* create() {X* r = new X;X->read();return X;}
virtual A* clone() const = 0;
};
class B : public A {
B():A() { };
friend class A;
public:
void read() { /*Do something special for B here.*/ }
B* clone() const {return new B(*this);}
};
class C : public A {
C():A() { };
friend class A;
public:
void read() { /*Do something special for C here.*/ }
C* clone() const {return new C(*this);}
};
Added a clone-method with covariant return type as a bonus.
Using CRTP:
class A {
public:
// This never needs to be called
virtual void read() = 0;
virtual A* clone() const = 0;
};
template<class D, class B> struct CRTP : B {
D* clone() {return new D(*this);}
static D* create() {return new D();}
};
class B : public CRTP<B, A> {
B() { };
public:
void read() { /*Do something special for B here.*/ }
};
class C : public CRTP<C, A> {
C() { };
public:
void read() { /*Do something special for C here.*/ }
};
One way to achieve this, would be simply to delegate it to another class (that is perhaps a friend) and can be sure to be called when fully constructed.
class A
{
friend class C;
private:
C& _c; // this is the actual class!
public:
A(C& c) : _c(c) { };
virtual ~A() { };
virtual void read() = 0;
};
class B : public A
{
public:
B(C& c) : A(c) { };
virtual ~B() { };
virtual void read() {
// actual implementation
};
};
class C
{
private:
std::unique_ptr<A> _a;
public:
C() : _a(new B(*this)) { // looks dangerous? not at this point...
_a->read(); // safe now
};
};
In this example, I just create a B, but how you do that can depend on what you want to achieve and use templates on C if necessary, e.g:
template<typename VIRTUAL>
class C
{
private:
using Ptr = std::unique_ptr<VIRTUAL>;
Ptr _ptr;
public:
C() : _ptr(new VIRTUAL(*this)) {
_ptr->read();
};
}; // eo class C
The workaround is to call the virtual function after construction. You can then couple the two operations (construction + virtual call) in factory function. Here is the basic idea:
class FactoryA
{
public:
A *MakeA() const
{
A *ptr = CreateA();
ptr->read();
return ptr;
}
virtual ~FactoryA() {}
private:
virtual A *CreateA() const = 0;
};
class FactoryB : public FactoryA
{
private:
virtual A *CreateA() const { return new B; }
};
// client code:
void f(FactoryA &factory)
{
A *ptr = factory.MakeA();
}
As mentioned by Benjamin Bannier, you can use CRTP (a template which defines the actual read() function.) One problem with that method is that templates have to always be written inline. That can at times be problematic, especially if you are to write really large functions.
Another way is to pass a function pointer to the constructor. Although, in a way, it is similar to calling the function in your constructor, it forces you to pass a pointer (although in C++ you could always pass nullptr.)
class A
{
public:
A(func_t f)
{
// if(!f) throw ...;
(*f)();
}
};
class B : A
{
public:
B() : A(read) {}
void read() { ... }
};
Obviously, you have the "can't call other virtual functions" problem within the read() function and any function it calls. Plus, variable members of B are NOT yet initialized. That is probably a much worst problem in this case...
For that reason, writing it this way is safer:
B() : A()
{
read();
}
However, in cases like that, that may be the time when you an some for of init() function. That init() function can be implemented in A() (if you make it accessible: i.e. use public A when deriving) and that function can call all the virtual functions as expected:
class A
{
public:
void init()
{
read();
}
};
class B : public A
{
public:
...
};
I know a lot of people say that an init() function is evil because people who create a B object now need to know to call it... but there isn't much else you can do. That being said, you could have a form of factory, and that factory can do the init() call as required.
class B : public A
{
public:
static B *create() { B *b(new B); b->init(); return b; }
private:
B() { ... } // prevent creation without calling create()
};
I have a weird C++ problem where I'm not sure if it works correctly this way or If I missed something.
There is a class A which inherits from ABase. ABase and A both have a method Generate() while A::Generate() should overwrite ABase::Generate().
Generate() is called out of the constructor of ABase.
Now my problem:
I do a new A() which first jumps into constructor of A and from there into constructor of ABase. ABase::ABase() now calls Generate(). What I want to do: A::Generate() should be executed (since this overwrites ABase::Generate()).
Unfortunately it seems out of the constructor of ABase only ABase::Generate() is called and never A::Generate().
I gues that happens because A is not fully constructed at this stage? Or is there a way to let ABase::ABase() make use of A::Generate()?
You do not want A::Generate() to be executed, since this
would involve executing a function on a class which has not been
constructed. C++ has been designed intentionally so that during
construction, the dynamic type of the object is the type being
constructed, precisely to avoid this sort of problem.
It's not easy to work around, and definitely not pretty, but you may be able to do something like this:
class ABase
{
public:
ABase()
{
// Normal constructor, calls `Generate`
}
virtual void Generate() { ... }
// ...
protected:
struct do_not_call_generate_tag {};
const static do_not_call_generate_tag do_not_call_generate;
ABase(const do_not_call_generate_tag)
{
// Same as the normal `ABase` constructor, but does _not_ call `Generate`
}
};
class A : public ABase
{
public:
A()
: ABase(ABase::do_not_call_generate)
{
// Other initialization
PrivateGenerate();
}
void Generate()
{
PrivateGenerate();
}
private:
void PrivateGenerate()
{
// Do what your old `Generate` does
}
};
In order to have nicely constructed and initialized objects, I would separate these two tasks from each other:
class ABase
{
public:
virtual void Generate()
{
//...
}
};
class A: public ABase
{
public:
virtual void Generate()
{
//...
}
};
Now you have to perform both tasks explicitly
A *someA = new A();
someA->Generate();
...but you can group this inside e.g. a Create() method or redefine the new operator or the like.
I was wondering how to do something in C++. I want to be able to create an instance of this struct
struct ComplexInstruction : simple_instr
{
bool isHead;
bool isTail;
};
that copies all the data from the simple_instr instance. So essentially, I want to do something like this
ComplexInstruction cInstr = instr; // <- instance of simple_instr
and have cInstr have a copy of all the data in instr without having to copy over every field (since there's alot of them). I'm not sure how do this, and I don't think simple casting will work. Additionally, is it possible to do the reverse? I.e. have an instance of ComplexInstruction and turn it into an instance of simple_instr. I assume this can be done using casting, but I don;t have alot of experience with c++
Thanks in advance
Create a consctructor in the derived class to initialize from a base class.
class Base
{
int x;
public:
Base(int a) : x(a){}
};
class Derived : public Base
{
public:
Derived(const Base & B) : Base(B){}
};
Note that if you have a derived object of Base, you actually have a base object and you can safely use the base copy ctor like so.
Derived d;
Base b(d);//the parts of Base that are in Derived are now copied from d to b.
//Rest is ignored.
If you want to be more verbose, you write an operator= in your derived class like
void operator=(const Base & b)
{
Base::operator=(b);
//don't forget to initialize the rest of the derived members after this, though.
}
It all depends on what you want to do, really. The important thing is: be explicit. Don't leave uninitialized members of your class.
You need to provide a constructor that takes an argument that is convertible to const simple_instr&:
struct simple_instr {
int i;
simple_instr(): i(0) { }
explicit simple_instr(int i): i(i) { }
};
struct ComplexInstruction: simple_instr {
explicit ComplexInstruction(const simple_instr& simple):
simple_instr(simple), isHead(false), isTail(false) { }
bool isHead;
bool isTail;
};
int main() {
simple_instr instr;
ComplexInstruction cInstr(instr);
}
Here I chose an explicit constructor, but depending on the semantics, an implicit one could also be appropriate. Only if the constructor is implicit, the =-style initialization works without casting.
Edit: This is not the best way to accomplish this, please look at the other answers.
This will do what you are looking for.
struct ComplexInstruction : simple_instr
{
ComplexInstruction(const simple_instr &simple)
{
*((simple_instr*)this) = simple;
}
bool isHead;
bool isTail;
};
Then ComplexInstruciton complex = simple; will call the conversion constructor. ComplexInstruction's copy construct casts this to its base class and the = will call simple_instr's copy constructor, which by default is a bitwise copy.
I have two classes in a class hierarchy where a parent class needs to have an instance of a class derived from it as a member variable. As an example:
class B;
class A {
public:
B* binst;
A();
};
class B : public A {
};
A::A() {
binst = new B;
}
Obviously, this causes an infinite recursion in the constructors, because to create a new B you have to call A's constructor, which creates a new B which calls A's constructor, and so ad infinitum.
Is there a way around this? The problem I'm having in this is that A has to have a B in it, but B must be derived from A, and there's not a way to prevent that.
To get an idea of why I need to do this, consider an object oriented hierarchy for a scripting language (like python or ruby or lua, etc):
All instances of anything are derived from a base class, Object.
Object has a method lookup table, which is an instance of MethodTable.
MethodTable is derived from Object, and must be, for the scripting language to be able to operate on it.
"Object has a method lookup table"
"MethodTable is derived from Object"
Putting aside coding concerns, do these statements really make sense together from even a conceptual standpoint? Should a MethodTable have its own MethodTable which then has its own MethodTable... etc?
I'd say it sounds like you need to refactor your concepts a bit. For instance, perhaps Object itself should somehow be responsible for exposing the necessary pieces of its MethodTable member. Thus not requiring MethodTable itself to be an Object. (There may be various other feasible designs too. It's hard to say without deeper knowledge of the actual project.)
Edit: Typically, compiler/implementation-internal types don't derive from language-dependent types. If you look at the internals of Java, their inheritance implementation won't derive from Object. Object is a language construction, it's part of your language's interface. A method table is part of the implementation. A method table should not be operated on by the language, it should be operated on by the implementation.
Moreover, enforced deriving from Object is a stupid thing to do and it happens because you didn't consider the language design and how the users were going to write generic code properly. This is especially true in dynamically typed languages like Lua or Python.
Object could have a private MethodTableImpl member and a public getter that returns a MethodTable. MethodTable contains a MethodTableImpl and derives from Object.
I don't know the purpose of your classes but here is a suggestion :
class A
{
public:
virtual void func DoIt () = 0;
...
};
class B : public virtual A
{
public:
};
class C : public virtual A ,B
{
void func DoIt () { /* statements */ }
};
now there is only 1 instance of class A.
It would be helpful to understand exactly are you trying to achieve via this construct.
As you've noted yourself, this is effectively like having A's constructor construct an instance of A, and that's an unavoidable path to stack overflow.
A more general solution would be to provide a set_subclass method for a pointer to an instance of A, which could then be populated by any subclass of A, not just B.
class A {
public:
A();
virtual ~A();
set_subclass(A* sub) { subclass = sub; }
private:
A* subclass;
};
// List(1) or Stream(2) using inheritance
struct B;
struct A {
B *inst;
A(B *inst_) : inst(inst_) {}
A() : inst(0) {}
};
struct B : A {
B(B *_inst) : A(inst) {}
// chose option 1 or 2
B() : A() {} // option 1: List
B() : A(0) {} // same as above
B() : A(this) {} // option 2: Stream
};
auto B3 = new B(new B( new B));
// This is either a length 3 list (1)
// or a stream (2) implemented by self ref 3rd element
You can make a constructor for class A which accepts a pointer to an object to class B and assign this pointer instead of allocating a new B:
A::A(B* b) : binst (b) {}
And in the construct of class B you pass 'this' in constructor of A:
B::B() : A(this) {}
The compiler will probably complain about it, but you can try. (It is ugly, though.)
Note that you can NOT use the binst pointer to access object B in A's constructor, because it's not fully constructed yet.
Does it actually need the binst as a member, or does it simply need to access it?
class B;
class A {
public:
B& binst(); //throws exception if not derived from B
A() {}
virtual ~A() {} //effectively required for the dynamic_cast
void foo();
};
class B : public A {
public:
void bar() {};
};
B& A::binst() {return dynamic_cast<B&>(this);}
void A::foo() {return binst().bar();}
I've trying to achieve something like this:
class Base
{
public:
Base(string S)
{
...
};
}
class Derived: Base
{
public:
int foo;
string bar()
{
return stringof(foo); // actually, something more complex
};
Derived(int f) : foo(f), Base(bar())
{
};
}
Now, this doesn't work as I want, because bar() is called in the Derived constructor before foo is initialized.
I considered adding a static function similar to bar() which takes foo as a parameter - and using that in the initialization list, but thought I'd ask if there were any other techniques that could be used to dig myself out of this one...
Edit: Thanks for feedback - here's how I was going to handle the static function. Not sure if the overload between a static and non-static function is too clever, but...
class Derived: Base
{
public:
int foo;
static string bar(int f)
{
return stringof(f); // actually, something more complex
}
string bar()
{
return bar(foo);
};
Derived(int f) : Base(bar(f)) , foo(f)
{
};
}
Yes, using a function (static class method or regular function) that takes foo as a parameter and returns a string is a good solution. You can call this same function from Derived::bar to prevent code duplication. So, your constructor would look like this:
Derived(int f) : Base(stringof(f)), foo(f) {}
I place the call to the Base constructor first in the list to emphasize the order in which the initializations occur. The ordering of the initializer list has no effect as all class members are initialized in the order that they are declared in the class body.
This is a very clean, functional approach to the problem. However, if you still would like to weigh alternatives then consider using composition instead of inheritance for the relationship between the Derived and Base classes:
class Base {
public:
Base(string S) { ... }
void bat() { ... }
};
class Derived {
Base *base;
int foo;
public:
Derived(int f) : base(NULL), foo(f) {
base = new Base(bar());
}
~Derived() {
delete base;
}
string bar() {
return stringof(foo); // actually, something more complex
}
void bat() {
base->bat();
}
};
You will need to consider the pros and cons for your specific situation. With Derived holding a reference to Base you gain greater control over the initialization order.
You can only call static functions in the initializer list. The way you have it in your code:
class Derived: Base
{
public:
int foo;
string bar()
{
return stringof(foo); // actually, something more complex
};
Derived(int f) : foo(f), Base(bar())
{
};
}
Will still initialize Base first, and then foo. The order of how you write things in an constructor initializer list does not matter in any way. It will always construct in this order:
First, all virtual base classes
Then the non-virtual base classes in the order they appear in the base-classes list
Then all member objects in the order they are defined in the class definition.
Thus, you end up calling stringof with an uninitialized value. This problem is solved in boost::base_from_member. Also note that calling any nonstatic member function before all the constructor initializers of all base-classes completed is undefined behavior.
Calling static functions, however, is totally fine:
class Derived: Base
{
public:
int foo;
static string bar(int f)
{
return stringof(f); // actually, something more complex
};
Derived(int f) : Base(bar(f)), foo(f)
{
};
}
The base class constructor always gets called before initializing the other members of the derived class; your compiler should be giving you a warning for having the initializers in the wrong order. The only correct solution is to make bar() a static method that takes f as a parameter.
The constructor is for, well, constructing the object. This means that, until it returns, there isn't an object there, and therefore that calling member functions just isn't going to work reliably. As everybody else says, use a static function or a non-member function.
I've been wanting to do this as well, but I gave up in the end.
Any suitable function call could be used as the parameter of Base().
Another option is to add and alternative constructor to Base that takes an int and does the conversion to 'string' itself.
Just move your constructor code to an Initialize() function and call it from the constructor. This is much simpler than static/nonstatic overriding or anything like that.