I have a abstact base class that calls a virtual method in it's constructor. after passing a shared_ptr
of the base class the implementation of the method is not found.
class a
{
public:
a() { fill(); }
protected:
virtual void fill() = 0;
}
class b : public a
{
public:
b() : a();
protected:
virtual void fill() { // do something }
}
....
shared_ptr<a> sptr = shared_ptr<a> ( new b()): // error happens here on runtime
When executing this I get a SIGABRT because it tries to execute the virtual void fill() = 0;
All the instances point to the same object, and share access to one "control block" that increments and decrements the reference count whenever a new shared_ptr is added, goes out of scope, or is reset. When the reference count reaches zero, the control block deletes the memory resource and itself.
std::shared_ptr is a smart pointer that retains shared ownership of an object through a pointer.
The difference is that std::make_shared performs one heap-allocation, whereas calling the std::shared_ptr constructor performs two.
You cannot call a pure virtual function from the constructor. At the time the constructor is running, the object is considered to be of the type being constructed, not of any derived type. Which means virtual dispatch "stops" at the type being constructed.
This means that calling fill()
from the constructor of a
will try to call a::fill()
, regardless of any derived classes of which this a
subobject can be part. And this of course fails miserably, since the function has no implementation.
Additionally, as @KerrekSB points out, your class needs a virtual destructor. Otherwise, you will get undefined behaviour if you ever delete
a b
instance via a pointer to a
(which is quite likely when shared_ptr<a>
is involved).
UPDATE Apparently, shared_ptr
is capable of using the default deleter properties to work around the necessity for a virtual destructor, so your class is technically OK not having one. Still, without a virtual destructor, you class depends on being managed in std::shared_ptr
s only; if you ever change that bit of design, you will run into trouble (and it will not be immediately obvious). I therefore suggest having a virtual destructor anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With