c++ - 将基类指针转换为派生类指针

标签 c++ casting

如以下代码所示,我正在尝试将基类指针转换为派生类指针。我期望以下代码会出现编译器错误,但不会报告任何错误。还有函数“SomeMethod_2”打印值 10。

#include <iostream>

using namespace std;

class Base {
public:
    Base() {
        cout << "Base class constructor\n";
    }

};

class Derived : public Base
{
public:
    int Val;
    Derived() {
        cout << "Derived class constructor\n";
    }
    void SomeMethod(void)
    {
        cout << "SomeMethod\n";

    }
    void SomeMethod_1(void)
    {
        Val = 10;
    }
    void SomeMethod_2(void)
    {
        cout << Val;
    }
};


int main()
{
    Base* BaseObj = new Base();

    Derived* DerivedObj = (Derived*) BaseObj;

    DerivedObj->SomeMethod();    # Expecting compiler error
    DerivedObj->SomeMethod_1();
    DerivedObj->SomeMethod_2();
    return 0;
}

最佳答案

强制转换,尤其是 C 风格的强制转换,告诉编译器关闭许多错误和警告,并且您保证您知道自己在做什么,风险由您自己承担。

在大多数情况下,使用不指向该类型对象的指针是未定义行为。未定义的行为就是这样——对可能发生的事情没有要求,所以你可能会遇到编译器错误或运行时错误。或者您可能认为它似乎“有效”(无论这意味着什么),或者完全出乎意料的事情。

就您的特定情况下实际发生的情况而言,这些函数很可能使用不属于 *BaseObj 的相邻内存来存储 int,但是后来这件事发生了无关紧要。但是,如果您记得删除 对象,那么此时您可能会遇到问题,因为覆盖的内存可能已被堆内存管理函数使用。

请注意,如果 Base 至少有一个虚函数(如析构函数),并且如果您使用更安全的 dynamic_cast 而不是最不安全的 C 风格转换,那么转换的结果将是空指针,因为 dynamic_cast 会检查对象是否确实属于该类型。

class Base {
public:
    Base() {
        cout << "Base class constructor\n";
    }
    virtual ~Base() = default;
};

// ...

int main()
{
    Base* BaseObj = new Base();

    Derived* DerivedObj = dynamic_cast<Derived*>(BaseObj);

    if (DerivedObj) {
        DerivedObj->SomeMethod();
        DerivedObj->SomeMethod_1();
        DerivedObj->SomeMethod_2();
    } else {
        std::cout << "Not a Derived\n";
    }

    delete BaseObj; // Don't forget to match every "new" with a "delete".
    return 0;
}

关于c++ - 将基类指针转换为派生类指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56795103/

相关文章:

c++ - C++中传递裸数组是什么意思

c++ - 初学者 C++ 练习的解决方案的意外输出

c++ - 为什么 std::optional 不允许对 "move construct and copy assign only"类型进行 move 赋值?

c# - 如何将 List 转换为继承自 List<T> 的类型?

c - C中多线程的整数转换问题

c++ - 隐式转换为用户定义类型

c++ - 从 c 数组创建 vector

c++ - const char* 到 int 转换?

Java:继承类不能在方法参数中转换为父类(super class)

c - 带逻辑运算符的有符号和无符号整数