我不明白为什么为类添加前向声明会更改其指向成员类型的指针的大小

#include <iostream>
using namespace std;

int main()
{
    //struct CL;
    //cout<<sizeof(int (CL::*)())<<endl;
    struct CL{};
    cout<<sizeof(int (CL::*)())<<endl;
}

VS2013输出:
4

但是,如果我取消注释main()中的前两行,则输出将不同:
16
16

因此,仅在结构CL的定义之前简单添加前向声明会增加指向CL成员的指针的大小。为什么?我知道成员函数指针的大小取决于类型的结构(例如,虚拟函数和基类可能会增加它的大小),但是为什么可以将sizeof运算符应用于指向不完整类型成员的指针?还是不能?我没有在标准中找到它

最佳答案

MSVC编译器将不同大小的成员函数指针用作优化。此优化违反了标准。 Igor Tandetnika MSDN form post中提到reinterpret_cast的荣誉,[expr.reinterpret.cast] p10



因此,有一个往返保证,这有效地强制符合规范的实现对所有指向成员函数类型的指针使用相同的大小。

如果设置了 /vmb switch,则执行MSVC优化。对于单继承,指向成员函数的优化指针仅需要void*大小的存储,请参阅The Old New Thing: Pointers to member functions are very strange animals

如果您只向前声明CL类型,然后形成一个指向成员的指针函数,则希望取消优化(不幸的是,我找不到关于它的任何文档)。否则,在CL的定义前后,您可能会得到不一致的大小。

顺便说一句,如果在不指定基础类型的情况下进行前向声明而又在以后为该枚举的定义显式定义基础类型的情况下进行声明,则VS2010中的枚举大小可能会不一致。这仅在激活语言扩展名的情况下起作用。

关于c++ - 指向不完整类型的成员函数的指针,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30923296/

10-11 22:46
查看更多