C++动态投稿,是不是多态的?

问题描述 投票:0回答:1

当我运行下面的代码时。

#include <iostream>

class Shape{
public:
};

class Square:public Shape
{
public:
};

class Circle:public Shape
{
    double r;
public:
    void SetRadious(double r)
    {
        std::cout << "R value:" << this->r <<std::endl;
        this->r=r;
    }
};

int main() {
    Shape * s = new Square();
    Circle* c= dynamic_cast<Circle*>(s);
    c->SetRadious(3.0);
    return 0;
}

我得到一个错误信息说:

'Shape' is not polymorphic(形状)。

我看了一下,发现我需要写一些虚拟函数,但是有2个问题。

1) 为什么要这样做,要求一个虚拟函数是没有意义的。

2) 在这种情况下,很多人说我需要虚拟的d'tor,但为什么默认的d'tor不会完全好,默认的d'tor和默认的d'tor有什么区别?

c++ class inheritance polymorphism dynamic-cast
1个回答
1
投票

1) 为什么要这样做

因为语言是这样说的。之所以这么说,是因为这种限制可以让程序更快。

要求一个虚拟函数是没有意义的。

对我来说,这很有意义。除非你有一个虚拟函数,否则我认为没有理由使用动态投射。坦率地说,即使是多态类,动态投射也很少有用。

2)在这种情况下,很多人说我需要虚拟d'tor,但为什么默认的不会完全好。

因为默认的不会是虚拟的。

你的例子泄露了内存。如果你试图通过以下操作来修复泄漏的内存 delete s;,那么程序的行为就会因为缺乏虚拟析构器而无法定义。


1
投票

像你现在这样的类的层次结构不是 多态 开箱即用。

dynamic_cast 要求层次结构是多态的。

使层次结构成为多态的最简单的方法是使基类的析构器成为 virtual:

class Shape {
    public:
        virtual ~Shape() = default;
};

这也有一个好处,就是你现在可以安全地打电话给 delete 的指针上 Shape* 其中动态类型是子类之一。

这背后的原因是多态性引入了可能不需要的运行时费用。这也意味着你的类失去了一些类似于C的特性,比如被称为 琐碎 类型。

请注意,一旦你引入了这个虚拟的析构器,那么 c

Circle* c = dynamic_cast<Circle*>(s);

将是 nullptr的行为,以及 c->SetRadius(3.0); 未定义。

© www.soinside.com 2019 - 2024. All rights reserved.