静态转换工作和动态转换段错误

以下代码编译并正常工作:

#include<iostream>

class Base {
    protected:
        int _a;

    public: 
        virtual ~Base()=default;
        Base(int a) : _a{a} {};

        int getit() const { return _a; }
};

class Derived : public Base {
    public:

        Derived(int a) : Base{a} {};
        int get2() const { return 2*this->_a; }
};

int main() {
    Base D{2};
    auto* ptr = &D;
    auto* ptr2 = static_cast<Derived*>(ptr);


    std::cout << ptr2->get2() << std::endl;
}

输出

4

如果我改变static_castdynamic_cast它出现segfaults。

我的问题:
使用static_cast强制转换为不添加任何数据成员的派生类是否安全?

回答

仅当对象的动态类型是派生类(或派生类是进一步派生的动态类型的基类)时。向上转换也是安全的,但这种转换也可以隐式工作。

如果您不知道是否是这种情况,并且 - 如示例中所示 - 当您知道情况并非如此时,这绝对不安全,并且示例程序的行为是未定义的。使用dynamic_cast是安全的,但不检查它是否返回 null,然后通过该 null 进行间接访问是不安全的。

总之,这将是安全的:

if (auto* ptr2 = dynamic_cast<Derived*>(ptr)) {
std::cout << ptr2->get2() << std::endl;
} else {
std::cout << "It's not Derived :(" << std::endl;
}

也就是说,如果您认为需要dynamic_cast,那么您可能应该重新考虑设计。您可能应该改用虚函数。例子:

class Base {
protected:
int _a;
public:
virtual ~Base()=default;
Base(int a) : _a{a} {};
virtual int getit() const { return _a; }
};
class Derived : public Base {
public:
using Base::Base;
int getit() const override { return 2*this->_a; }
};

以上是静态转换工作和动态转换段错误的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>