Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

shared_ptr does not find virtual method

Tags:

c++

shared-ptr

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;

like image 339
Steve Avatar asked Nov 26 '13 14:11

Steve


People also ask

What happens when shared_ptr goes out of scope?

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.

What is the purpose of the shared_ptr <> template?

std::shared_ptr is a smart pointer that retains shared ownership of an object through a pointer.

What is the difference between Make_shared and shared_ptr?

The difference is that std::make_shared performs one heap-allocation, whereas calling the std::shared_ptr constructor performs two.


1 Answers

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_ptrs 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.

like image 170
Angew is no longer proud of SO Avatar answered Nov 07 '22 22:11

Angew is no longer proud of SO