使用多个指向它的指针来管理对象
Posted
技术标签:
【中文标题】使用多个指向它的指针来管理对象【英文标题】:Managing an object with multiple pointers to it 【发布时间】:2019-02-14 10:55:56 【问题描述】:假设我有两个抽象类,A1
和 A2
。 A1
有一个名为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_A1
和 n_A2
,指定每个抽象类 A1
和 A2
有多少个实例。然后我定义了两个指针数组:
A1 **a1s = new A1*[n_A1];
A2 **a2s = new A2*[n_A2];
然后手动将实例的所有地址添加到这些数组中。例如,如果c1s
的长度为2,c2s
的长度为3,如果C1
继承A1
,C2
继承A2
,C3
继承A1
和A2
我会这样做:
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=3
和n_A2=4
现在可以遍历地址数组a1s 和a2s 并调用函数foo()
或bar()
。当删除包含所有这些对象的实例时,我只需要释放数组a1s
和a2s
。
一直被建议不要在 C++ 中使用原始指针,我想知道这是否是解决这个问题的好方法?这种方法有风险吗?有更好的方法吗?
【问题讨论】:
原始拥有指针有问题,"observer" 指针没问题。所以std::vector<A1 *>a1s&c1s[0], &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<IA>
的向量。
他的问题是关于使用原始指针,所以我当然要添加虚拟析构函数,但我认为使用unique_ptr
会偏离重点以上是关于使用多个指向它的指针来管理对象的主要内容,如果未能解决你的问题,请参考以下文章