Pyrrole 2021-03-30 09:19 采纳率: 100%
浏览 657
已采纳

有无大佬来解释一下这个指针为什么可以如此直接的调用了类中的私有成员变量,看着有点懵[face]mon

有无大佬来解释一下这个指针为什么可以如此直接的调用了类中的私有成员变量,看着有点懵

下面代码和运行结果:

#include <iostream> 
using namespace std; 
class test
{ 
private: 
    int num; 
public: 
    test(int n) : num(n){} 
}; 
int main()
{ 
    test t(1024);
    int* add = (int*)&t; 
    cout << *add << endl;   
    *add = 2048; 
    cout << *add << endl; return 0; 
}

  • 写回答

3条回答 默认 最新

  • 幻灰龙 2021-03-31 02:52
    关注

    C++ 的 class 没有虚函数表的时候,和 C 的 struct 在内存布局上没什么区别,这个时候 int* add = (int*)&t; 这里把取 t 的地址,这个地址指向的内存位置刚哈就是放第一个成员变量 int num 。因此你再强转成 int* 就得到了 num 的指针。然后对这个指针赋值,就修改了 num 的值。

     

    如果 C++ 的 class ,没有构造函数、没有析构函数、也没有虚函数表,那么有一个专有名词来称呼它: Plain Old Data, 也就是所谓的 POD 类型。当你需要跟很多 系统 API, 或者 C API 交互的时候,你总是会定义一些这样的 POD 类型,因为那些 API 接受的就是 C 的 struct 内存布局的对象的指针。

     

    此外,在 C++ 里面,语言提供给了程序员【自由的解释内存权限】,也就是,一个指针指向的内存,到底是什么,程序员自己在基于对 C++ 规范定义的内存规则的理解下,可以自由地将内存地址转成 void* 指针,然后你自己知道它是什么类型,传递到别的地方,那个地方再强转成你知道的正确的类型的指针。这往往会在一些需要传入不同类型指针的地方用到。C++ 为了规范,还提供了与此相关的转换函数有一组:static_cast, dynamec_cast, const_cast, reinterpret_cast。简单说,进入指针的世界,实际上就是你(程序员)自己决定你的代码是否对,当然如果不对,程序运行时你会获得一堆运行时异常。

     

    当然,一般来说,先别这么干,先用有类型的,常规的规则去写代码总是好的,因为基于隐式规则写的代码,你需要文档其他人才好读,毕竟程序员 70% 的时间是在读代码。

     

    推荐阅读《深入C++对象模型》这本书。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
    SoftwareTeacher 2021-03-31 03:28

    如果以后 test 类加上了一个函数,或者有其它改动, 这个已经工作的程序就会突然不工作了, 这种基于某种副作用的编程方法有很多隐患吧?

    回复
    幻灰龙 回复 SoftwareTeacher 2021-03-31 03:36

    对于这个具体的类,肯定不能这么写,在一些需要做C++提供实现导出C接口,做类似COM那样的继承的地方会用到。

    回复
    Pyrrole 2021-03-31 05:33

    谢谢大佬

    回复
查看更多回答(2条)
编辑
预览

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部