将shared_ptr与多继承类一起使用

时间:2014-05-26 14:57:59

标签: c++ inheritance multiple-inheritance smart-pointers

我有一个继承两个接口的类:

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

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

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

不幸的是,对于每个接口,此类不能在两个单独的类中进行分解。事实上,在类实现中,这些实体(Foo和Bar)紧密耦合,但将来它们可能会分开。

另一个类想要使用Multi类,指向IFoo和IBar:

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

在构造函数中,我执行以下操作:

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

但是每个共享指针都有单独的引用计数器,它会导致在类破坏时删除已经删除的指针,对不对?

  1. 我应该如何对待它?
  2. 这种情况的最佳实践是什么?

2 个答案:

答案 0 :(得分:8)

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

将确保他们具有相同的参考计数器。你可以自己看看:

#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;
}

产生

base1 usecount = 3
base2 usecount = 3
derived usecount = 3

答案 1 :(得分:0)

我不确切地知道你想用这些指针做什么,但另一种解决方案可能是存储一个std::unique_ptr<multi> multi_;并有几个接口函数静态地将它转换为普通指针或者引用:

IFoo& ClientClass::get_ifoo() {
  return *(static_cast<IFoo*>(multi_.get())); 
}

IBar& ClientClass::get_ibar() {
  return *(static_cast<IBar*>(multi_.get())); 
}

只要你没有将这些内容从课堂上传出来,并且不打电话给delete[],就应该非常安全。