想象一下,我有一个Base类和两个派生自它的类One和Two。在Java中,我可以有以下情形:在C++中实例化派生类型
Base b;
if(condition)
b = new One();
else
b = new Two();
在对象类型在运行时确定(上述目的去堆)。我希望能够在运行时实例化对象类型 - 我所知道的是它们都共享相同的Base类型 - 但我想保留它的堆栈分配,如下所示:
Base b;
这样做的最好方法是什么?
想象一下,我有一个Base类和两个派生自它的类One和Two。在Java中,我可以有以下情形:在C++中实例化派生类型
Base b;
if(condition)
b = new One();
else
b = new Two();
在对象类型在运行时确定(上述目的去堆)。我希望能够在运行时实例化对象类型 - 我所知道的是它们都共享相同的Base类型 - 但我想保留它的堆栈分配,如下所示:
Base b;
这样做的最好方法是什么?
这样做的最好方法是什么?
你不行。如果你声明一个变量类型为Base
,那么它的堆栈分配将适用于持有Base
的实例,但不适用于派生类型的实例(它可能较大,尽管不是,但仍不能完成你的任务问; C++中的变量的运行时类型始终与其声明的类型相同)。充其量,您可以将slice派生实例转换为Base
-类型的变量。
最好的选择是使用一个指针,可选地包装在shared_ptr
或unique_ptr
中给你类似的语义。假定所有权没有被转移时,该对象在超出范围时自动销毁)。
Base* b = (condition) ? (Base *) new One() : new Two();
auto bptr = shared_ptr<Base>(b);
注意,这是什么让你实际上是一样的Java。对象本身是堆分配的,但是对它的引用是堆栈分配的。尽管有语法,但引用类型的Java变量本质上等同于C++中的指针。
为了在C++中使用继承,您需要定义一个指针而不是静态对象,然后使用new
关键字对其进行实例化。
实施例:
Base* b;
if(condition)
b = new One();
else
b = new Two();
采取的,例如:
Derived d;
Base* b = &d;
d
是堆栈(自动存储器)上,但仍然多态性将在b
工作。
如果您没有基类指针或对派生类的引用,则多态性不起作用,因为您不再具有派生类。就拿
Base c = Derived();
的c
对象不是Derived
,但Base
,因为切片。因此,从技术上讲,多态性仍然有效,只不过你不再有一个对象来谈论。
现在采取
Base* c = new Derived();
c
只是指向内存的某个地方,你真的不关心这是否是实际上是一个Base
或Derived
,但调用的virtual
方法将被动态解析。
所以,看起来,与Java不同,没有堆分配或指针方式,没有办法实现动态绑定。
正如评论说你不能。嗯,你可以但不会运行:
Base &b = *(condition ? (Base *)&One() : (Base *)&Two()); // BROKEN CODE DO NOT USE
(构建使用-fpermissive
,但不这样做!)
因为One
& Two
对象是临时对象。 b
一旦你通过下一行就会无效=>不这样做(不知道我已经说过了)
以下工作,但不完美:在堆栈上构建两个对象,所以只有在你可以负担得起。根据条件只要选择:
One one;
Two two;
Base &b = *(condition ? (Base *)&one : (Base *)&two);
为了避免双重分配,我能想到的在使用方面最接近的事是采取分配的对象的引用(还没有自动变量,不好意思):
Base &b = *(condition ? (Base *)new One() : (Base *)new Two());
因此,您可以在代码中使用b
作为Base
。
你还有如果你想成为堆栈中分配你的对象与
delete (&b);
对不起,我没有测试过的唯一代码:)修复。 –
删除记忆 - 有没有(Java不分配堆栈上的对象,所以这2例是不相同)。即使你可以,你的对象也会被[切片](http://stackoverflow.com/questions/274626/what-is-object-slicing)为“Base”类型。 –
你不能(以任何通知可维护的方式)。它是堆栈分配的,所以它的大小必须在分配时已知。记住在Java中你的对象不是堆栈分配的,所以虽然用C++编写的Java代码暗含了堆栈分配,但并不意味着在Java中。 – djgandy
这是经典的XY问题 - http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – Slava