this pointer to base class constructor? - c++

I want to implement a derived class that should also implement an interface, that have a function that the base class can call. The following gives a warning as it is not safe to pass a this pointer to the base class constructor:
struct IInterface
{
void FuncToCall() = 0;
};
struct Base
{
Base(IInterface* inter) { m_inter = inter; }
void SomeFunc() { inter->FuncToCall(); }
IInterface* m_inter;
};
struct Derived : Base, IInterface
{
Derived() : Base(this) {}
FuncToCall() {}
};
What is the best way around this? I need to supply the interface as an argument to the base constructor, as it is not always the dervied class that is the interface; sometimes it may be a totally different class.
I could add a function to the base class, SetInterface(IInterface* inter), but I would like to avoid that.

You shold not publish this from the constructor, as your object is not yet initialized properly at that point. In this actual situation, though, it seems to be safe, since you are publishing it only to the base class, which only stores it and does not invoke it until some point later, by which time the construction will have been finished.
However, if you want to get rid of the warning, you could use a static factory method:
struct Base
{
public:
Base() { }
void setInterface(IInterface* inter) { m_inter = inter; }
void SomeFunc() { inter->FuncToCall(); }
IInterface* m_inter;
};
struct Derived : Base, IInterface
{
private:
Derived() : Base() {}
public:
static Derived* createInstance() {
Derived instance = new Derived();
instance->setInterface(instance);
return instance;
}
FuncToCall() {}
};
Note that the constructor of Derived is private to ensure that instantiation is done only via createInstance.

You can always defer the interface dereference:
struct IInterface
{
virtual ~IInterface();
virtual void FuncToCall() =0;
};
class Base
{
public:
virtual ~Base();
void SomeFunc() { GetInterface().FuncToCall(); }
private:
virtual IInterface& GetInterface() =0;
};
class Derived: public Base, public IInterface
{
public:
private:
virtual IInterface& GetInterface() { return *this; }
virtual void FuncToCall();
};

There is a limited set of operations that you can do (guaranteed by the standard) with a pointer to a yet uninitialized object, and storing it for further use is one of them. The compiler is probably warning as it is easy to misuse the received pointer in Base.
Beware that most uses of the pointer for other than storage will be undefined behavior, but the code above is correct.

What is quite funny is that you could get away with it by initializing it later on:
Derived::Derived(): Base()
{
this->setInter(this);
}
is fine, because all attributes have been initialized.
This way you won't have to change your whole design just to get away with the warning.
However, unless the setInter does not do anything with this apart some storage, you might access an object you did not fully initialized (so storing a hash value could be awkward).

how about:
struct IInterface
{
void FuncToCall() = 0;
IInterface* me() { return this; }
};
...
struct Derived : IInterface, Base
{
Derived() : IInterface(), Base(me()) {}
FuncToCall() {}
};
at the point we get to Base constructor IInterface is already initialized, so the call to me() is safe, and warning free

what about using protected: for IInterface* m_inter;
struct IInterface
{
virtual void FuncToCall() = 0;
};
struct Base
{
Base(IInterface* inter) { m_inter = inter; }
void SomeFunc() { m_inter->FuncToCall(); }
protected: // or `public:` since you are using `struct`
IInterface* m_inter;
};
struct Derived : Base, IInterface
{
//Derived() : Base(this) {} // not good to use `this` in the initialization list
Derived() : Base() { m_inter = static_cast<IInterface*>(this); }
FuncToCall() {}
};

Related

convert an object created with base class ctor to a derived class

I have the following classes:
class Base {
public:
virtual ~Base(){}
Base() {}
virtual void foo() = 0;
};
class Derived : public Base {
public:
virtual ~Derived(){}
Derived() : Base() {}
void foo() { printf("derived : foo\n"); }
};
class IInterface {
public:
virtual ~IInterface() {}
virtual void bar() = 0;
};
class C : public Derived, public IInterface {
public:
virtual ~C(){}
C() : Derived(){}
void bar() { printf("C : bar\n"); }
};
now I have a bunch of Derived* objects and I want to apply different interfaces on them :
Derived* d = new Derived();
C* c = dynamic_cast<C*>(d);
c->bar();
c->foo();
dynamic_cast returns nullptr and with c-style cast i get seg fault.
is there anyway to achieve this?
note that my objects are already created with Derived ctor.
i just want to treat them differently using Interfaces
The only way to achive this is to create a new object and move the data over from the old object.
Try encapsulating the behaviour that needs to change at runtime. Instead of inheriting from the IInterface, you have a member variable that is an IInterface pointer. Then instead of overriding bar in the child class, you pass the call to bar through to whatever is being pointed at. This allows modular behavior that looks just like polymorphism, but is more flexible:
class IInterface {
public:
virtual ~IInterface() {}
virtual void bar() = 0;
};
class Derived : public Base {
public:
IInterface* m_bar;
virtual ~Derived(){}
Derived() : Base(){}
void bar() {return m_bar->bar(); }
void foo() { printf("derived : foo\n"); }
};
You then derive and create IInterface objects and can associate any of them with Derived objects.

C++: How to enforce derived class to set base member variables?

I have a base class with a member variable (preferably private) and I need to enforce derived classes to initialize it with a value based on their implementation; much like a pure virtual function.
To clarify, I want to declare a member in Base, have derived classes initialize it, and if they don't they get a compiler error. In the following code, I declared default constructor of Base to be protected. Then declared default constructor of Derived to be private.
class Base {
private:
int _size;
protected:
Base(){}
/* pure virtual methods */
public:
Base(int size) : _size(size){} // must enforce derived to call this.
virtual ~Base(){}
/* more pure virtual methods */
};
class Derived : public Base {
private:
Derived() {}
public:
Derived(int size) : Base(size) {
//Base::Base(size);
}
};
int main()
{
Derived* d1 = new Derived(); // throws an error as needed:
// "Cannot access private member declared in class 'Derived'"
Derived* d2 = new Derived; // throws an error as needed:
// "Cannot access private member declared in class 'Derived'"
Derived* d3 = new Derived(5); // works as needed
return 0;
}
The problem with the above code is that if another definition of Derived doesn't hide the default constructor. I'm still stuck with an uninitialized Base::_size.
I don't know if there is another way to go about this other than inheritance, because I still need derived classes to implement their own behavior for several methods declared in Base.
Any pointers are appreciated.
After the confusion about calling a base class ctor and default ctors, maybe the solution is just to not have a default ctor in Base?
class Base {
private:
int _size;
public:
// no default ctor
Base(int size) : _size(size) {} // must enforce derived to call this.
virtual ~Base(){}
/* more pure virtual methods */
};
class Derived : public Base {
public:
// no default ctor
Derived(int size) : Base(size){
}
// examplary default ctor:
//Derived() : Base(42) {}
};
int main()
{
Derived d1; // error: no default ctor
Derived* d2 = new Derived; // same, but why use the free store?
Derived d3(5); // works as needed
Derived* d4 = new Derived(5); // same, but why use the free store?
return 0;
}
To be explicit about not having a default ctor, one could use
class Base {
/* ... */
Base() = delete;
/* ... */
};
Use a constructor
class Base1 {
protected:
Base1(int forward) {
thingYouWantToHide = forward;
}
private:
int thingYouWantToHide;
};
class Derived1: public Base1 {
public:
Derived1(): Base1(5) {}
};
class Base2 {
private:
int value;
protected:
Base2() {
value = calledToGet();
}
virtual int calledToGet() = 0;
virtual ~Base2() {} //shut compiler warnings up
};
class Derived2: public Base2 {
virtual int calledToGet() {
return 5;
}
};
int main(int,char**) {
Derived1 a;
Derived2 b;
return 0;
}
You may think Derived2 will work, but remember Derived2 is not constructed until Base2 is, so that virtual is an undefined reference when Base2 is being constructed.
You should use the first case, type-traits if it is a constant (static const) or fundamental to the type.

defer the initalization of boost::scoped_ptr

I have defined a member variable as follows. Since the variable will not be passed around, so I decide to use scoped_ptr rather than shared_ptr here.
class ClassName
{
public:
ClassName()
{
Initialize();
}
virtual void Initialize() = 0;
protected:
boost::scoped_ptr<int> m_scpInt;
}
class ClassNameB : public ClassName
{
public:
virtual void Initialize()
{
m_scpInt.reset(new int(100));
}
}
Due to the limit of the scoped_ptr, if I decide to defer the initialization of the variable in a later time, the only option I get is to call reset.
Q1> Is this a good practice?
Q2> Otherwise, is there a better solution?
Thank you
/// Updated -1 ///
This is what I really want to do.
I want to enforce that each of the derived class define a function called Initialize and which in turn calls function InitializeVarA and InitializeVarB. As you indicate, that we cannot call virtual function in the constructor.
class ClassName
{
public:
ClassName()
{
}
virtual void Initialize()
{
InitializeVarA();
InitializeVarB();
}
protected:
virtual void InitializeVarA() {}
virtual void InitializeVarB() {}
}
class ClassNameB : public ClassName
{
public:
ClassNameB()
{
}
virtual void Initialize()
{
InitializeVarA();
InitializeVarB();
}
protected:
virtual void InitializeVarA() {}
virtual void InitializeVarB() {}
}
ClassNameB cb;
cb.Initialize();
Do I have a better solution than this?
Is this a good practice?
Using reset to reset a scoped pointer is fine.
Trying to initialise a derived class by calling a virtual function from the base class's constructor is not just bad practice; it's wrong. At that point, the dynamic type of the object is the base class, and the function is pure virtual, so calling it gives undefined behaviour.
Even if you made it non-pure, you still can't call the derived class's override at that point, so the pointer won't be reset.
Otherwise, is there a better solution?
You could do it in the derived class's constructor, which is invoked immediately after the base class's:
class Base {
public:
Base() { /* don't call any virtual functions here */ }
protected:
boost::scoped_ptr<int> p;
};
class Derived : public Base {
public:
Derived() {
p.reset(new int(100));
}
};
Or you could pass the allocated memory to the base class constructor and initialise the pointer from that. That's slightly dangerous though - you must make sure you initialise the pointer immediately, before anything that might throw an exception, or the memory might leak.
class Base {
public:
Base(int * p) : p(p) {}
private: // doesn't need to be protected now
// (unless something else in the derived class needs access)
boost::scoped_ptr<int> p;
};
class Derived : public Base {
public:
Derived() : Base(new int(100)) {}
};
In C++11, you could use unique_ptr, which is movable, to avoid that risk of a leak:
class Base {
public:
typedef std::unique_ptr<int> ptr;
Base(ptr && p) : p(p) {}
private:
ptr p;
};
class Derived : public Base {
public:
Derived() : Base(ptr(new int(100))) {}
};

c++ inheritance pointer

it's pretty diffecult for me to describe my problem.
I have two classes, I would say Base_A and Derived_A. You can see from the names, the class Derived_A is derived from Base_A. Also in my program I have other two classes Base_B and Derived_B (also with inheritance). The class Base_A contains the object of Base_B, and the class Derived_A contains the object of Derived_B.
class Base_A {
public:
Base_A() {}
virtual ~Base_A() {}
Base_B b_;
Base_B* pointer_;
void init() {
b_ = Base_B();
pointer_ = &b_;
pointer_->setValue(1);
}
void print() {
pointer_->getValue();
}
};
class Derived_A: public Base_A {
public:
Derived_A() {}
virtual ~Derived_A() {}
Derived_B b_;
Derived_B* pointer_;
void init() {
b_ = Derived_B();
pointer_ = &b_;
pointer_->setValue(2);
pointer_->increaseValue();
}
};
class Base_B {
public:
Base_B() {}
virtual ~Base_B() {}
int value_;
void setValue(int value) {
value_ = value;
}
void getValue() {
cout << "Base_B: " << value_ << endl;
}
};
class Derived_B: public Base_B {
public:
Derived_B() {}
virtual ~Derived_B() {}
void increaseValue() {
value_++;
}
};
int main() {
Derived_A derived_A = Derived_A();
derived_A.init();
derived_A.print();
return 0;
}
How you can see every class of A has one object of class B and pointer to this object. My problem is, when I call the function print(), it does not take Derived_B* pointer_, but try to access Base_B* pointer_, which is not exist. How I can say in my program, that it should take the pointer according to the class? Or do I need to declarate the Base_B* pointer_ inside the Derived_A class like:
Base::pointer_ = pointer_;
Maybe is there other method or algorithm for my problem?
Thank you a lot.
"but try to access Base_B* pointer_, which is not exist"
If DerivedA does not properly initialise BaseA, then DerivedA does not meet the "isA" rule for inheritance and the design needs changed. On the face of things:
Don't re-use names in the derived class such as b_, pointer_.
Its just confusing and you gain no value.
Make init() virtual.
Have DerivedA::init() call BaseA::init() explicitly.
Make pointer_ a virtual method.
Note the use of "covariant return types" for the virtual methods.
class BaseA
{
public:
virtual BaseB* pointer() { return &b_; }
// etc.
};
class DerivedA : public BaseA
{
public:
virtual DerivedB* pointer() { return &b_; }
// etc.
};
wouldn't Base_A have a pointer to Base_B if Base_A::init() was ever called?
why wouldn't you init the base class?

How can I get polymorphic behavior in a C++ constructor?

I have a base class that I want to look like this:
class B
{
// should look like: int I() { return someConst; }
virtual int I() = 0;
public B() { something(I()); }
}
The point being to force deriving classes to override I and force it to be called when each object is constructed. This gets used to do some bookkeeping and I need to know what type of object is being constructed (but I otherwise treat the current object as the base class).
This doesn't work because C++ won't let you call an abstract virtual function from the constructor.
Is there a way to get the same effect?
Based on this link it would seem that the answer is there is no way to get what I want. However what it says is:
The short answer is: no. A base class doesn't know anything about what class it's derived from—and it's a good thing, too. [...] That is, the object doesn't officially become an instance of Derived1 until the constructor Derived1::Derived1 begins.
However in my case I don't want to know what it is but what it will become. In fact, I don't even care what I get back as long as I the user can (after the fact) map it to a class. So I could even use something like a return pointer and get away with it.
(now back to reading that link)
You can't call virtual methods from the constructor (or to be more precise, you can call them, but you'll end up calling the member function from the class currently being constructed)., the problem is that the derived object does not yet exist at that moment. There is very little you can do about it, calling virtual methods from the constructor polymorphically is simply out of the question.
You should rethink your design -- passing the constant as an argument to the constructor, for example.
class B
{
public:
explicit B(int i)
{
something(i);
}
};
See C++ faq for more. If you really want to call virtual functions during construction, read this.
Perhaps use a static factory method on each derived type? This is the usual way to construct exotic objects (read: those with very specific initialisation requirements) in .NET, which I have come to appreciate.
class Base
{
protected Base(int i)
{
// do stuff with i
}
}
class Derived : public Base
{
private Derived(int i)
: Base(i)
{
}
public Derived Create()
{
return new Derived(someConstantForThisDerivedType);
}
}
Calling virtual methods in base constructors is generally frowned upon, as you can never be certain of a particular method's behaviour, and (as somebody else already pointed out) derived constructors will not have yet been called.
That will not work as the derived class does not yet exist when the base class constructor is executed:
class Base
{
public:
Base()
{
// Will call Base::I and not Derived::I because
// Derived does not yet exist.
something(I());
}
virtual ~Base() = 0
{
}
virtual int I() const = 0;
};
class Derived : public Base
{
public:
Derived()
: Base()
{
}
virtual ~Derived()
{
}
virtual int I() const
{
return 42;
}
};
Instead you could add the arguments to the base class constructor:
class Base
{
public:
explicit Base(int i)
{
something(i);
}
virtual ~Base() = 0
{
}
};
class Derived : public Base
{
public:
Derived()
: Base(42)
{
}
virtual ~Derived()
{
}
};
Or if you're really fond of OOP you could also create a couple of additional classes:
class Base
{
public:
class BaseConstructorArgs
{
public:
virtual ~BaseConstructorArgs() = 0
{
}
virtual int I() const = 0;
};
explicit Base(const BaseConstructorArgs& args)
{
something(args.I());
}
virtual ~Base() = 0
{
}
};
class Derived : public Base
{
public:
class DerivedConstructorArgs : public BaseConstructorArgs
{
public:
virtual ~DerivedConstructorArgs()
{
}
virtual int I() const
{
return 42;
}
};
Derived()
: Base(DerivedConstructorArgs())
{
}
virtual ~Derived()
{
}
};
What you need is two-phase construction. Use the Universal Programmer's cure: Add another layer of indirection.