使用新的OK隐式向下转换?

时间:2014-09-04 15:58:38

标签: c++ inheritance new-operator derived-class downcast

您如何看待这段C ++代码:

Polygon* p;
if(shape=="Rectangle")
    p = new Rectangle();
else if(shape=="Triangle")
    p = new Triangle();
else
    exit(EXIT_FAILURE);

其中Rectangle和Triangle派生自基类Polygon。

它背后的想法是我需要使用派生类中的特定方法,而不知道在程序运行之前我需要哪个类。 有没有更好的方法呢?它编译,但我想知道是否调用所选派生类的析构函数,以便正确释放特定变量。

辅助问题:dynamic_cast操作是否涉及数据副本?

谢谢:)

修改

感谢您提供所有这些非常有益的答案。

现在让我们说方法

bool isIsosceles()

在Triangle中实现,但不在Rectangle中实现。

然后立即打电话

p->isIsosceles()

显然会失败。

我的第一个想法是:

声明并实现isIsosceles()作为基类Polygon中的虚方法

virtual bool isIsosceles()
{ 
    cout << "Isosceles means nothing to me." << endl;
    exit(EXIT_FAILURE);
}

或在if语句中使用dynamic_cast。

这些选项中的任何一个都是一个好习惯吗?

非常感谢

4 个答案:

答案 0 :(得分:2)

  

使用新的OK隐式向下转换吗?

这里没有“向下倾斜”:这是对多态行为的直接使用。你的Polygon *是指向基类的指针;构造代码生成一个对象,通过使用虚拟成员函数抽象出实现。

  

它编译,但我想知道是否调用了所选派生类的析构函数,以便正确释放特定变量。

如果基类中的析构函数是虚拟的(它应该是),通过基类指针释放对象将正确地执行所有操作:

delete p;
  

有更好的方法吗?

您可以使用std::unique_ptr<Polygon>自动删除Polygon对象的过程。当指针超出范围时,使用智能指针会破坏对象。

  

dynamic_cast操作是否涉及数据副本?

我假设你在这里没有使用dynamic_cast,因为Polygon为所有感兴趣的操作声明了虚拟成员函数。但是,当您执行dynamic_cast时,不会进行数据复制。系统检查是否允许强制转换,并为您提供正确的强制转换指针,或返回nullptr

答案 1 :(得分:1)

如果您记得delete p并且Polygon的析构函数为virtual,则会有效。这很重要。

更好的选择是将其包装在智能指针中。

答案 2 :(得分:0)

这不是向下倾斜。你实际上在这里使用多态,即创建一些你将用作基类型对象的派生类型的对象。

您可以这样做,但与使用new分配的所有内容一样,请使用delete。另外需要注意的是,您需要在Polygon中使用虚拟析构函数,如下所示:

class Polygon {

    virtual ~Polygon();
}

否则你最终会得到对象切片,也就是你会有“半删除”的对象。

附加说明:仅供参考,使用您的课程,向下转换将执行以下操作:

Polygon* polygon = new Triangle();

Triangle* triangle = dynamic_cast<Triangle*>(polygon);

// Check that we effectively had a triangle under this polygon pointer
if(triangle){
     //do something with the triangle
}

答案 3 :(得分:0)

  

它背后的想法是我需要使用派生类中的特定方法,而不知道在程序运行之前我需要哪个类。

这种方法违背了多态的目的,它允许你在不知道你正在使用的派生类型的情况下执行操作。

  

有更好的方法吗?

这取决于你最初想要实现的目标。例如,您展示的内容可以作为类工厂的一部分实现。你创建它们之前没有展示过如何使用这些对象,所以很难说你是否做得对不对。

  

我想知道是否调用了所选派生类的析构函数,以便正确释放特定变量。

仅当~Polygon()声明为virtual时才会这样。

  

dynamic_cast操作是否涉及数据副本?

没有。 dynamic_cast只是执行运行时查找以获取指向同一对象的VMT的不同部分的指针。