I have two classes, for instance, A and B. I would like to pass A as reference to B.
class I
{
public:
virtual void callback() = 0;
};
class B
{
public:
B(I* callback) : _callback(callback) {}
private:
I* _callback;
};
class A : public I
{
public:
A() : _b(new B(this)) {}
private:
B* _b;
};
And I would like to:
get rid of naked pointers (for instance, with a help of std::shared_ptr and std::weak_ptr).
avoid cyclic referencing.
But there are some problems:
How do I create a weak pointer INSIDE a class A? First, I should be sure that an instance of A is managed by some shared_ptr. Even if I'm really sure, how can I find this shared_ptr instance?
Generally, how can I ensure that I'm using instances of some class ONLY via shared pointers? I can try to create factory method and make constructor private, but it leads to error: make_shared demands a public contstructor.
Thanks in advance!
EDIT:
More detail explanation of problem: I have a class A. This class wants to pass some part of work to a class B. So I have a shared pointer to B inside A. And I would like B to do this asynchronously, and B should call A's callback when there is some progress or when the work is done. So B should have a reference to A.
class I
{
public:
virtual void isDone() = 0;
};
class B
{
public:
B(I* callback) : _callback(callback) //how do I take and store callback inside B???
{
//async invocation of run()
}
private:
weak_ptr<I> _callback;
void run()
{
if(_callback.get())
{
_callback->isDone();
}
}
};
class A : public I
{
public:
A() : _b(new B(this)) {} //how do I pass this to B???
private:
shared_ptr<B> _b;
virtual void isDone()
{
cout << "job is complete" << '\n';
}
};
So the question is: how do I pass A to B? I can try to do it via naked pointer or reference, but it's safety because B has no guarantees that this referenced object is still alive (common problem of all naked pointers). So I would like to pass a weak pointer, and my question was all about it.
The first problem can be solved with std::enable_shared_from_this, which allows you to safely create a shared pointer instance from within class A.
The second problem may be solved by using a static factory method belonging to class A and not using std::make_shared like this:
static std::shared_ptr<A> create() {
return std::shared_ptr<A>(new A());
}
Then, you can make A's constructor private.
Related
I'm trying to implement something following the decorator pattern, but I cannot seem to obtain from a shared_ptr the same run-time behaviour I can get through normal pointers.
I have a basic class I (interface) with a virtual method, then I derive from it two classes:
class A (component) which will contain some data
class B (decorator) which derives from I and also contains a pointer to it and will implement some additional behaviour. I have a constructor that initialises the pointer to a certain I (or derived) object.
Then I want to be able to build a B object with its pointer pointing to an A, so that when I call the common methods I call the A ones not the I ones.
I can do this if I make the pointer in B in the usual way (in the code example, see the class B_basic and the object bb in the main).
But if I make this pointer like a shared_ptr to I it calls the method from I even if I build it pointing to an actual A (in code see the B_shared class and the object bs)
class I {
public:
virtual void method() {cout<<"I\n";}
virtual ~I() = default;
};
class A : public I {
public:
virtual void method() {cout<<"A\n";}
};
class B_shared : public I {
public:
shared_ptr<I> shared_pointer;
B_shared(const I& i) : shared_pointer(make_shared<I>(i)) {}
virtual void method() {
cout<<"B_shared > ";
shared_pointer->method();
}
};
class B_basic : public I {
public:
I* basic_pointer;
B_basic(I* i) : basic_pointer(i) {}
virtual void method() {
cout<<"B_basic > ";
basic_pointer->method();
}
};
int main() {
A a;
B_shared bs(a);
B_basic bb(&a);
bs.method(); // B_shared > I
bb.method(); // B_basic > A
}
What am I doing wrong?
This is object slicing.
In the following line you make a copy of the instance i of type A to type I. Thus the original type A is sliced to base type I.
shared_pointer(make_shared<I>(i))
In raw pointer version basic_pointer(i), you save the pointer itself, no slicing.
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 know that this code won't work and I also know why, but is there an alternative?
class A
{
public:
A(void){}
virtual ~A(void){}
protected:
A* parent;
int a;
};
class B : public virtual A
{
public:
B(void){}
virtual ~B(void){}
protected:
void f(){ ((B*)parent)->a; }
};
It is not possible to cast parent to a B*, since A is a virtual base class. Not casting parent also gives an error. I hope I don't have to make all members public. Does someone have an idea how to access A::a?
Edit
Using friends doesn't work, since classes derived from B don't have access to A::a.
Some options:
Make a public
Create a public setter/getter method for a -
make B a friend of class A (or just the function f())
The 3rd option his works better than the other 2 if you want to allow only A (or a specific function) to have access to members of A. On the other hand with the other 2 options you can make only that member public (but it will be public to everyone)
Making an answer from my comment above because I tested it and it compiles fine.
Without the cast, it probably fails because you are trying to access a protected field of A in B. You can just add a public getter and remove the cast to B*
class A
{
public:
A(void){}
virtual ~A(void){}
int getA() { return a; }
protected:
A* parent;
int a;
};
class B : public virtual A
{
public:
B(void){}
virtual ~B(void){}
protected:
void f(){ (parent)->getA(); }
};
This works:
class A {
public:
A(void){}
virtual ~A(void){}
protected:
A* parent;
int a;
int parent_a(){ return parent->a;}
};
class B : public virtual A
{
public:
B(void){}
virtual ~B(void){}
protected:
void f(){ A::parent_a(); }
};
Note that:
a doesn't get exposed to the outside world,
the retrieved a is necessary the correct one, since B inherit virtually from A, so a successful dynamic cast of parent to B before getting its a field should return the same one as the solution offered above.
Now, why does this work?
Because a class is implicitely friend of itself.
That's what dynamic_cast is for. If you don't want to redesign your code, just replace the C-style cast with a dynamic_cast:
void f() { dynamic_cast<B*>(parent)->a; }
For this to work correctly, A must have at least one virtual function (as this one does). In addition, the cast will produce a null pointer if parent does not, in fact, point to an object of type B.
class B : public virtual A
{
public:
B(void){}
virtual ~B(void){}
protected:
void f(){ this->a; }
};
you're allowed to access protected member from parent class (A mother class of B).
I think the problem here is not so much how to access the element a, but why you need a tree of diamond hierarchies in your design. You should at first step back and evaluate if you really need a tree of diamonds.
If you do, then instead of your current approach, provide A with a nice appropriate (public) abstract interface that can be called from B. When you start accessing parent protected attributes directly you tightly couple components, making it easy to break your code and making it very hard to change your design later in the application's lifespan.
Thanks everyone, some usable possibilities were mentioned, like using friends and creating additional functions for each variable. This could work in some scenarios, but not in my case. Adding each derived class as a friend has the problem that it makes the library less user friendly when they want to add a class. Adding functions per variable would add over hundred extra functions for some classes.
What I did as my final solution was creating a copy instead of a cast. Though it will run a little bit slower, the code will remain clean. To counter the speed problem. Accessing local variables is a lot faster than accessing global variables.
This is how it looks now:
class A
{
public:
A* parent;
virtual ~A(void){}
virtual A & operator = (const A & x)
{
a = x.a;
parent = x.parent;
return *this;
}
protected:
int a;
};
class B : public virtual A
{
public:
B(void){}
virtual ~B(void){}
using A::operator =;
virtual B & operator = (const B & x)
{
A::operator = (x);
return *this;
}
void f(void)
{
B p;
p = *parent;
int x = p.a;//Allowed.
}
};
If you have a better solution, please feel free post it.
i have this :
class A {
public :
A(int i ) : m_S(i)
{
m_Pa = new Foo(*this) ;
}
private :
int m_S ;
Foo* m_Pa;
}
and derived class
class B : public A {
public :
B() : A (242)
{
// here i like to override the A class m_Pa member but i don't know how to do it right
}
}
your m_Pa should be protected than you can call like:
B() : A (242), m_Pa(12)
{
}
or
B() : A (242)
{
m_PA = 55
}
or you should make a public or protected function which changes m_Pa
class A {
public :
A(int i ) : m_S(i)
{
m_Pa = new Foo(*this) ;
}
void setPA(int val)
{
m_PA = val;
}
What is m_Pa? You never had it declared. Assuming it's a private data member of type Foo* in class A, you can't directly change it in the derived class unless you change A's interface. E.g., you can provide a protected setter member function:
class A {
....
protected:
void setFoo(const Foo* foo);
}
class B {
....
Foo *foo = new Foo(this);
setFoo(foo);
}
You can't override member variables in a derived class, only methods.
Short answer: By declaring m_Pa private, you are saying that only class A should be able to modify it. So you cannot alter its value using methods of class B.
Longer answer: In C++ (and most other object oriented programming languages), you not only declare the type of a member, but also its visibility (public, protected and private). This allows you to enfore encapsulation of data: You only expose an interface, but you do not let clients of your class modify its internals directly.
In your concrete example, I would create accessors
Foo* getPa() {
return m_Pa;
}
void setPa(Foo* Pa) {
m_Pa = Pa;
}
in class A and use them in class B to modify m_Pa. If you would like class B (but not unrelated classes) to be able to modify m_Pa declare getPa() and setPa() in a protected: section of your class; if you would like any client to modify them declare them in a public: section. Especially in the later case you need to start worrying about object ownership, i.e. which object is responsible for deleting the object stored in m_Pa which is created in the constructor. A practical solution to this problem is to use smart pointers, see for instance boost's implementation.
A note on terminology: "Overriding" a member in C++ usually refers to giving a new implementation of a virtual member function. So if your class A has a method
virtual void doIt()
then a member of the same type in class B overrides the implementation of A's doIt().