将 shared_ptr 与多继承类一起使用

Posted

技术标签:

【中文标题】将 shared_ptr 与多继承类一起使用【英文标题】:Using shared_ptr with multi inheritance class 【发布时间】:2014-05-26 14:57:58 【问题描述】:

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

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);  

但是这些共享指针中的每一个都有单独的引用计数器,它会导致在类销毁时删除已删除的指针,对吗?

    应该如何治疗? 这种情况的最佳做法是什么?

【问题讨论】:

看起来您现在应该将 IFoo 和 IBar 分开。 :) @Jerry 我无法将它们分开,因为它们有共同的初始化、共同的发布等,我无法更改。 【参考方案1】:
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

【讨论】:

你确定 shared_ptr 的赋值运算符允许使用不同的模板类型作为参数吗? shared_ptr = shared_ptr ? @vard 可以,只要右边的类型是从左边的继承而来的。【参考方案2】:

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

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


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

只要你不把它们从课堂上传出去,也不给它们打电话delete[],应该是很安全的。

【讨论】:

这里还需要演员表吗? (即这些功能没有意义。) @juanchopanza 在更深入的研究中我看到了,但是共享指针的想法应该是这样,对吧?

以上是关于将 shared_ptr 与多继承类一起使用的主要内容,如果未能解决你的问题,请参考以下文章

std::shared_ptr 和继承

将 django ORM 与多处理一起使用?

将 kapt 与多平台子项目一起使用

将构建任务与多目标解决方案一起使用

单继承与多继承

python 示例说明如何将实例方法与多处理模块一起使用