派生类实例以共享相同的基类实例

ida*_*hmu 6 c++ inheritance

假设我有一个Proc具有以下界面的类:

class Proc
{
public:
  void process();
protected:
  virtual void do_process() = 0;
private:
  int m_counter;
};
Run Code Online (Sandbox Code Playgroud)

现在,假设我有两个实现Proc接口的派生类.

class DerivedProc1:
  public Proc
{
protected:
  virtual void do_process();
};

class DerivedProc2:
  public Proc
{
protected:
  virtual void do_process();
};
Run Code Online (Sandbox Code Playgroud)

现在我生成两个派生类:

Proc* dp1 = new  DerivedProc1();
Proc* dp2 = new  DerivedProc2();
Run Code Online (Sandbox Code Playgroud)

我想这两个dp1dp2共享同一个基类的实例.
我需要的原因是因为Proc::m_counter在两个处理器中必须是相同的,这意味着,在一个处理器中改变它的值必须被另一个处理器"看到".当然,Proc::m_counter这只是我想要分享的变量的一个例子.
这个问题的标准方法是什么?

笔记

我不是在寻找快速解决问题的方法.含义:

  1. 制作Proc::m_counter static是不可取的.我仍然需要它绑定到特定的Proc实例.
  2. 我不想在m_counter外面Proc和传递作为参考proc

Ste*_*sop 5

如上所述,这是不可能的.以下要求相互矛盾:

  • 计数是实例的数据成员DerivedProc1,而不是"在...之外Proc".
  • count是实例的数据成员DerivedProc2.
  • 实例DerivedProc1和实例DerivedProc2是通过单独调用分配的new,也就是说它们是不同的最派生对象.

不同的大多数派生对象不能共享数据成员.原因是定义了最派生的对象以占用其自己的内存区域.只有同一个派生对象的子对象才能共享成员.

如果你愿意放宽"外部存储"限制,那么解决方案是"显而易见的":让每个对象保持一个shared_ptr带有计数的东西.将相同的计数保持对象传递给您希望共享计数的任何对象的构造函数.使这个问题困难的唯一方法是限制计数在内存中的位置.

如果您愿意放宽"单独new调用"限制,那么您可以使用虚拟继承并将两个Proc对象构造为单个最派生对象的基类子对象:

class DerivedProc1 : public virtual Proc { ... };
class DerivedProc2 : public virtual Proc { ... };

class CombinedProc : public DerivedProc1, DerivedProc2 { ... };

CombinedProc *dp0 = new CombinedProc();
DerivedProc1 *dp1 = dp0;
DerivedProc2 *dp2 = dp0;
Run Code Online (Sandbox Code Playgroud)

由于没有一个类有虚析构函数,你必须使用dp0(而不是dp1dp2)删除对象.如果你给Proc一个虚拟析构函数,那么你可以使用它们中的任何一个(并且只有一个).

除非你正确理解它,否则我不建议使用虚拟继承.因此,由于您将不得不放松其中一个要求,我通常会说标准方法是放松第一个:将计数存储在两个对象之外的单独对象中.