V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gaoan000
V2EX  ›  C++

请教一个指针转换问题

  •  
  •   gaoan000 · 2020-03-19 15:35:02 +08:00 · 1811 次点击
    这是一个创建于 1492 天前的主题,其中的信息可能已经有所发展或是发生改变。

    变量 pFun 为一个指向成员函数的指针,类型为 void(Test::*)()

    如果把这个指针转换为 int*类型,方法我自己试了出来,但是不明白为什么要这么写 int *pInt = (int *&)pFun;

    按我的理解,转换应该为(int *)pFun,可以帮忙解惑下吗?

    6 条回复    2020-04-18 14:28:23 +08:00
    wutiantong
        1
    wutiantong  
       2020-03-19 15:38:14 +08:00
    你怎么写都是 ub 呀
    gaoan000
        2
    gaoan000  
    OP
       2020-03-19 15:50:13 +08:00
    @wutiantong 是说我没定义吗, 怕影响篇幅没人看

    class Test{
    public:
    void fun1(){
    cout << 123 << endl;
    }
    };

    typedef void (Test::*pMember)();
    pMember pFun = &Test::fun1;
    yulon
        3
    yulon  
       2020-03-19 16:21:34 +08:00
    标准就不想让你转,但大部分实现可以用 *reinterpret_cast<const void *const *>(&mem_ptr) 或 *reinterpret_cast<const uintptr_t *>(&mem_ptr),这是基于内存布局的,用 C++ 尽量不要用 C 式转换,如果要转成 int * 可以把第一条的 void 换成 int,但是根据严格别名规则,编译器可能会忽略你对解引用后的 int & 的任何操作,所有读取或修改都不会被编译。
    wutiantong
        4
    wutiantong  
       2020-03-19 16:27:31 +08:00
    @gaoan000

    ub 是未定义行为的意思: https://zh.cppreference.com/w/cpp/language/ub

    显示类型转换的规则是: https://zh.cppreference.com/w/cpp/language/explicit_cast
    你用的是第一类( C 风格转型表达式)

    如果要转成(int *),static_cast 和 reinterpret_cast 都帮不了你;

    如果要转成(int * &),则会落入 reinterpret_cast 的第六条: https://zh.cppreference.com/w/cpp/language/reinterpret_cast
    具体是:
    6) T1 类型的左值表达式可转换成到另一个类型 T2 的引用。结果是与原左值指代同一对象,但有不同类型的左值或亡值。不创建临时量,不进行复制,不调用构造函数或转换函数。只有类型别名化( type aliasing )规则允许(见下文)时,结果指针才可以安全地解引用
    gaoan000
        5
    gaoan000  
    OP
       2020-03-19 16:51:18 +08:00
    @yulon
    @wutiantong
    感谢两位的解答,被 C++的一些规则绕进去了.非常感谢
    Wirbelwind
        6
    Wirbelwind  
       2020-04-18 14:28:23 +08:00
    2 级的转换可以让编译器检测不到这个行为。

    仅仅*是一级 *&是二级
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2283 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 00:49 · PVG 08:49 · LAX 17:49 · JFK 20:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.