使用多个指向它的指针来管理对象

Posted

技术标签:

【中文标题】使用多个指向它的指针来管理对象【英文标题】:Managing an object with multiple pointers to it 【发布时间】:2019-02-14 10:55:56 【问题描述】:

假设我有两个抽象类,A1A2A1 有一个名为foo() 的函数,A2 有一个名为bar() 的函数。我为这些基类创建了许多不同的子类,比如C1,C2,C3,...,它们可能继承也可能不继承A1 和/或A2. 我现在想遍历A1 类型的所有类和所有A2 类型的类并调用 foo()bar()。我的问题是实现这一目标的最佳方法是什么?我的方法是使用包含C1,C2,... 实例的智能指针或向量,即:

std::vector<C1> c1s;
std::vector<C2> c2s;
std::unique_ptr<C3> c3;
...

然后我声明两个整数,n_A1n_A2,指定每个抽象类 A1A2 有多少个实例。然后我定义了两个指针数组:

A1 **a1s = new A1*[n_A1];
A2 **a2s = new A2*[n_A2];

然后手动将实例的所有地址添加到这些数组中。例如,如果c1s 的长度为2,c2s 的长度为3,如果C1 继承A1C2 继承A2C3 继承A1A2 我会这样做:

a1s[0]=&c1s[0];
a1s[1]=&c1s[1];
a2s[0]=&c2s[0];
a2s[1]=&c2s[1];
a2s[2]=&c2s[2];
a1s[2]=c3.get();
a2s[3]=c3.get();

因此n_A1=3n_A2=4 现在可以遍历地址数组a1s 和a2s 并调用函数foo()bar()。当删除包含所有这些对象的实例时,我只需要释放数组a1sa2s

一直被建议不要在 C++ 中使用原始指针,我想知道这是否是解决这个问题的好方法?这种方法有风险吗?有更好的方法吗?

【问题讨论】:

原始拥有指针有问题,"observer" 指针没问题。所以std::vector&lt;A1 *&gt;a1s&amp;c1s[0], &amp;c1s[0], c3.get();(尽管必须注意指针的有效性)。 “不使用原始指针”是一个不幸的神话。 “使用原始拥有指针”是邪恶的 强烈推荐阅读:When should I use raw pointers over smart pointers?。来自已接受答案的示例引用:“如果没有所有权的概念,从不使用智能指针。” 您可以使用observer pattern 另外,你问了很多问题(我数了四个)。我们应该回答哪一个? 【参考方案1】:
class IA

   virtual ~IA();


class A1 :public  IA

   virtual ~A1();
   virtual void foo();


class A2 :public  IA

   virtual ~A2();
   virtual void bar();


class C1 :public  A1

   virtual ~C1();
   virtual void foo();

class C2 :public  A2

   virtual ~C2();
   virtual void bar();

class C3 :public A1,public A2

   virtual ~C3();
   virtual void foo();
   virtual void bar();


int main()

  std::vector<IA*> AllAsObjects;
  AllAsObjects.push_back(new C1());
  AllAsObjects.push_back(new C2());
  AllAsObjects.push_back(new C3());
  for (IA* Obj :AllAsObjects)
  
    if(dynamic_cast<A1*>(Obj))
      dynamic_cast<A1*>(Obj)->foo();
    if(dynamic_cast<A2*>(Obj))
      dynamic_cast<A2*>(Obj)->bar();
  

我认为这就是你所需要的

*注意它是自编译的

【讨论】:

IA 类应该有虚拟析构函数。而且,最好使用std::unique_ptr&lt;IA&gt;的向量。 他的问题是关于使用原始指针,所以我当然要添加虚拟析构函数,但我认为使用unique_ptr 会偏离重点

以上是关于使用多个指向它的指针来管理对象的主要内容,如果未能解决你的问题,请参考以下文章

C++ 管理对象

动态内存管理

使用智能指针来管理对象 (基于RAII)

智能指针

智能指针和动态内存

[C++11新特性] 智能指针详解