Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using shared_ptr with multi inheritance class

I have an class which inherit two interfaces:

class Multi : public IFoo, public IBar {
public:
  virtual ~Multi();

  // Foo part
  virtual void fooMethod();
  // ...

  // Bar part
  virtual void barMethod();
  // ...
};

Unfortunately this class cannot be decomposed in two separate classes for each interface. In fact in class implementation those entities (Foo and Bar) are tightly coupled, but in future they could become separate.

Another one class wants to use Multi class, having a pointer to IFoo and IBar:

class ClientClass {
    public:
       ClientClass(); // constructor
       // smth
    private:
       std::shared_ptr<IFoo> foo_;
       std::shared_ptr<IBar> bar_;
};

In constructor I do something like:

ClientClass::ClientClass(){
    auto pMulti = new Multi;
    foo_ = std::shared_ptr<IFoo>(pMulti);
    bar_= std::shared_ptr<IBar>(pMulti);  
}

But each of those shared pointers has separate reference counter, and it leads to deleting already deleted pointer on class destruction, am I right?

  1. How should I treat it?
  2. What is best practics for such case?
like image 471
vard Avatar asked May 26 '14 14:05

vard


1 Answers

ClientClass::ClientClass()
{
    auto pMulti = std::make_shared<Multi>();
    foo_ = pMulti;
    bar_ = pMulti;  
}

would ensure that they have the same reference counter. You can see it for yourself:

#include <iostream>
#include <memory>

class Base1{};
class Base2{};
class Derived : public Base1, public Base2 {};

int main()
{
    auto derived = std::make_shared<Derived>();
    std::shared_ptr<Base1> base1 = derived;
    std::shared_ptr<Base2> base2 = derived;

    std::cout << "base1 usecount = " << base1.use_count() << '\n';
    std::cout << "base2 usecount = " << base2.use_count() << '\n';
    std::cout << "derived usecount = " << derived.use_count() << '\n';

    return 0;
}

produces:

base1 usecount = 3
base2 usecount = 3
derived usecount = 3
like image 92
Martin Drozdik Avatar answered Sep 19 '22 13:09

Martin Drozdik