使用new运算符将对象复制到堆而不知道其类型

jll*_*dom 9 c++ inheritance new-operator

我有一个疑问,下面的函数可以接收类型A的对象或派生类型的东西.

A *copyToHeap(A &obj) {
    A *ptr=new A(obj);
    return ptr;
}
Run Code Online (Sandbox Code Playgroud)

如果我们这样称呼它:

//B inherits from A
B bObj;
B *hPtr=copyToHeap(bObj);
Run Code Online (Sandbox Code Playgroud)

指向的对象hPtr实际上是A型还是B型?这样做安全吗?

Ner*_*ron 8

当您在代码中执行以下操作时:

A* ptr = new A(obj);
Run Code Online (Sandbox Code Playgroud)

你将永远得到一个A实例.obj将被视为A,新的A将基于obj的"A部分"创建.

更好的方法是在早期的回复中指出,将虚拟MakeCopy方法添加到基类并为派生类实现它.

virtual A* MakeCopy();
Run Code Online (Sandbox Code Playgroud)

通过制作其调用对象的副本来实现此方法.然后它在派生类中实现,所以如果你有一个实际上是B对象的A指针,你将获得一个真正的B副本并避免在你的例子中出现的"切片".


Luc*_*ore 5

返回的对象是类型pointer to A,这意味着指向的对象hPtr是类型A.这是不安全的,因为调用B独有的方法或成员将导致崩溃或未定义的行为.你可能正在寻找工厂模式.