如以下代码所示,我正在尝试将基类指针转换为派生类指针。我期望以下代码会出现编译器错误,但不会报告任何错误。还有函数“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/