在 C++ 中转换指针后访问 class 的成员

Accessing members of class after casting pointer in C++

我是 C++ 的新手。 谁能告诉我为什么下面的源代码运行良好?

#include <iostream>

using namespace std;

class A{
public:
    A(){ cout << "create a" << endl; }
    void sayGoodbye() { cout << "goodbye" << endl; }
};

class B{
public:
    B() { cout << "create b" << endl; }
    void sayHello() { cout << "hello" << endl; }
};

int main(array<System::String ^> ^args)
{
    A* a = new A();

    ((B*)a)->sayHello();
    a->sayGoodbye();

    return 0;
}

输出:

create a
hello
goodbye

我想知道为什么 a 可以通过这样的转换访问 B::sayHello? 它可以通过这种方式访问​​任何 class 的每个 public 成员吗?

是的,你可以。

但是,不,你不能。

当您使用这样的 C 风格转换时,您向计算机承诺您知道自己在做什么,并且转换是有效的。当它 有效时,你就没事了。如果不是,那就是的错。

在这种情况下,不是,这是你的错。

现在,您可以问为什么 "runs well",但这是偶然的:那纯属偶然。一旦程序被编译,如果你真的访问无效内存,它只会崩溃或谋杀你的继子。在这种特殊情况下,您没有访问无效内存。

但这并不意味着你是对的。

不要这样做。

由于您为 classes A 和 B 定义的函数不依赖于那些 classes 中存储的任何数据,因此计算机不必读取任何内容 运行 的功能,他们能够执行。

不过,一般来说,如果 sayHello 方法需要读取存储在 B class 上的数据,您的转换会导致段错误或其他一些严重问题,因为这会使计算机读取它被告知分配到内存中以适合 B 类型的对象,但事实并非如此,因为该对象是 A 类型的。

sayHello 方法未从 class B 访问任何数据成员。此外,((B*)a)->sayHello(); 被编译为类似于 call-to-mangled-sayHello-member-function-of-B(this ) 。因此,class B 成员函数 sayHello 将通过传递指向 B 对象的指针来调用,并且该指针未在 sayHello 方法中使用。因此,它将在这种情况下起作用。

((B*)0)->sayHello();
((B*)1)->sayHello();
((B*)2)->sayHello();

事实上,以上所有调用都可以。 sayHello 将收到地址为 0、1、2 的 this 指针。因为 sayHello 没有访问 B 的任何数据成员,所以它们将起作用。如果 sayHello 访问任何非静态数据成员,那么就会发生大崩溃。通常,行为是未定义的。 如果 sayHello 是虚拟的,那么就会出现真正的问题。因为,在那种情况下,将需要内存中的有效对象来在运行时解析被调用的函数。

This 不是您问题的答案,但它可以在使用指针转换时为您提供更多知识和选择:

您可以看到以下几种铸造技术:

static_cast
dynamic_cast
const_cast
reinterpret_cast
C-style cast (type)value
Function-style cast type(value)

在我的例子中,我使用 dynamic_cast 来检查这个转换问题。它在向下转换的情况下也很有帮助。 但是向下转换中 dynamic_cast 的一个问题是我们必须具有多态 class 类型。