从指向基类的指针调用派生类的复制构造?
Posted
技术标签:
【中文标题】从指向基类的指针调用派生类的复制构造?【英文标题】:Invoke the copy construction of a derived class from a pointer to the base class? 【发布时间】:2015-06-01 01:29:05 【问题描述】:我有
1- class A int m;;
2- class B: public A
float n;;
3- class C: public A
string n;;
我将A类的所有实例都存储在
vector <class A*> myInstansesofA;
它被存储为一个指针,因为我根据一些 if 语句动态创建它们
if (some condition)
A* newA = new B();
myInstancesofA.push_back(newA );
else
A* newA = new C();
myInstancesofA.push_back(newA );
现在我需要创建矢量的精确副本。使用新的指针集,但数据的精确副本。
问题在于将 A 的每个实例(实际上是 B 和 C)的数据复制到新向量。
我尝试了以下方法,但它不起作用。
for (vector<A*>::const_iterator it = myInstancesofA.begin(); it != myInstancesofA.end(); ++it)
A* newA = new A(*(*it));
myInstancesofA.push_back(newA );
我怀疑发生此错误是因为“new A”仅调用类型 A 的复制构造函数,而不调用 B 或 C(我调试并发现这种情况正在发生)。
我该如何解决这个问题?
【问题讨论】:
【参考方案1】:我相信你不能像那样调用构造函数,并且在 C++ 中没有直接的方法来做类似的事情(对于像 Java 和 C# 这样的反射语言来说,这是非常简单的)。
一种方法是使用prototype pattern
class A
public:
virtual A* clone()
return new A ...;
;
class B : public A
public:
A* clone() override
return new B .........;
;
class C : public A
public:
A* clone() override
return new C .........;
;
对象本身负责创建自己的克隆。当然在设计上还有很多需要改进的地方,但至少它能让你体验一下。
【讨论】:
好线索,但有一些小细节:B
和C
应该从A
派生,并且new B()
比new B
慢(它需要在之前执行零初始化默认构造) - 没有理由在这里使用它;理想情况下,OP会添加构造函数来设置任何必要的字段并简化为例如return new B(...args...);
。最后,对于B::clone
和C::clone
,最好使用override
而不是virtual
。
@TonyD Gosh 我无法想象我错过了那些明显的东西,修复它们(我想我需要一些咖啡):P for new B()
我不知道你提到的差异,可以导致我要一些资料吗? (对不起,我知道的话题:P)
我也需要一杯咖啡!无论如何,在 C++11 标准 4.3.4/17 中要求“如果省略 new-initializer,则默认初始化对象(8.5);如果不执行初始化,则对象具有不确定的值。——否则, new-initializer 根据 8.5 的初始化规则进行解释,用于直接初始化。”,在 8.5/11 和 /17 下,()
不带参数意味着“值已初始化”,在 8.5/8 中进行了描述,如果存在则首先指定零初始化编译器提供的默认构造函数。以上是关于从指向基类的指针调用派生类的复制构造?的主要内容,如果未能解决你的问题,请参考以下文章
在 C++ 继承中,当指向基类的指针对象指向派生类时,不调用派生类析构函数