在C ++中实例化派生类型

时间:2016-11-10 15:06:37

标签: java c++

想象一下,我有一个Base类,以及两个派生自它的类,一个和两个。在Java中,我可以有以下场景:

Base b;
if(condition)
  b = new One();
else
  b = new Two();   

在运行时确定对象类型(上面的对象在堆上)。

在C ++中,我希望能够在运行时实例化对象类型 - 我所知道的是它们都共享相同的Base类型 - 但是我想保持它的堆栈分配,如下所示:

Base b;

最好的方法是什么?

4 个答案:

答案 0 :(得分:1)

  

最好的方法是什么?

你不能。如果将变量类型声明为Base,则它的堆栈分配将适合于保存Base的实例,但不适用于派生类型的实例(可能更大,但即使它是不,你仍然无法做你所要求的; C ++中变量的运行时类型总是与其声明的类型相同)。最好的情况是,您可以将派生实例slice转换为Base - 类型变量。

最好的办法是使用一个指针,可选地包含在shared_ptrunique_ptr中,以提供类似的语义(即,当对象超出范围时,让对象自动销毁,假设所有权还没有被转移。

Base* b = (condition) ? (Base *) new One() : new Two();
auto bptr = shared_ptr<Base>(b);

请注意,这给你的实际上与Java相同。对象本身是堆分配的,但对它的引用是堆栈分配的。尽管有语法,但引用类型的Java变量本质上等同于C ++中的指针。

答案 1 :(得分:0)

举个例子:

Derived d;
Base* b = &d;

d在堆栈上(自动内存),但多态仍然可以在b上运行。

如果您没有基类指针或对派生类的引用,则多态性不起作用,因为您不再具有派生类。取

Base c = Derived();

由于切片c对象不是Derived,而是Base。因此,从技术上讲,多态性仍然有效,只是你不再需要Derived个对象来讨论。

现在拿

Base* c = new Derived();

c只是指向记忆中的某个地方,而你真的不在乎这是Base还是Derived,而是对virtual方法将动态解决。

因此,似乎与Java不同,没有堆分配或指针方式就无法实现动态绑定。

答案 2 :(得分:0)

正如评论所说,你做不到。嗯,你可以,但那不会运行:

Base &b = *(condition ? (Base *)&One() : (Base *)&Two()); // BROKEN CODE DO NOT USE

(使用-fpermissive构建,但不要这样做!)

One&amp; Two个对象是临时对象。单步执行下一行=&gt; 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);

答案 3 :(得分:-1)

为了在C ++中使用继承,您需要定义一个指针,而不是静态对象,然后使用<div class="container"> <div class="row"> <div class="col-md-4 col-sm-4"> <div class="row"> <div class="col-md-12 border"> 1 </div> <div class="col-md-12 border"> 2 </div> </div> </div> <div class="col-md-4 col-sm-4"> <div class="row"> <div class="col-md-12 border long"> 3 </div> </div> </div> <div class="col-md-4 col-sm-4"> <div class="row"> <div class="col-md-12 border"> 4 </div> <div class="col-md-12 border"> 5 </div> </div> </div> </div> </div> 关键字对其进行实例化。

示例:

new