私人/保护/公众如何影响ABI

How private/protected/public affect the ABI?

本文关键字:影响 ABI 保护 私人 何影响      更新时间:2023-10-16

我想要的是某些类成员有时是private,而其他类Times public。某些模块应该可以访问这些成员,而其他模块则无法访问。

成像此类:

class Foo {
public:
    ...
private:
    ...
protected:
    ...
internal:
    int x;
};

在模块X中,internal定义为:

#define internal public

,在模块中,它被定义为:

#define internal private

因此,真正的问题是该技巧是否可以被标准接受,还是将以任何方式更改类(或其成员)的签名。

我知道friendPIMPL是用于这种工作的,但是friend可能会变得非常凌乱,并且PIMPL的性能(间接和您无法直列的事实)是我正在处理的代码库是不可接受的。。

这是odr违规行为,因此调用了未定义的行为。(另请参见Basic.def.odr]/6.1" D的每个定义应由同一代币序列组成")。

但是,一个普遍的实施是公共,私人保护对班级布局没有影响,因此它可以起作用。

你在薄冰上滑冰;没有什么可以阻止编译器将所有公共成员,然后是受保护的成员,然后是私人成员。总的来说,更重要的是,声明的顺序必须是内存中的顺序SO

struct T {char a; int b; char c};

必须具有a,然后是b,然后是c。这是为了确保C兼容性。但是,对具有不同访问访问的元素的排序不需要(请参阅[class.mem]/9.2 p13:"分配了具有相同访问控制(第11条)的(非工会)类的非静态数据成员,以便后来的成员在类对象中具有较高的地址。未指定具有不同访问控制的非静态数据成员的分配顺序(第11条)"。因此,给定

struct T {char a; int b; private: char c};

编译器可以重新排序成员,并将c放在ab之间的差距中。

对EJP和其他认为这些声明而不是定义的人的最终注释:我给出了上面T的两个定义;A 声明看起来像struct T;

编辑:感谢Fanael的标准。

C 最初似乎认为可以将私人成员放在公共成员旁边以外的地方,也许他们可以是硬件中受保护的地区,因此可以想象公众和公众私人部分可以相对于彼此移动。

可以测试您的代码而不使用Herb Stutter 76的技巧重新定义公共/私人,并在此处使用此数据完成了功能齐全的系统。

给出了一个类,如下..

struct A {
  A(int a):a(a) { }
private:
  int a;
};

需要一个强盗...

template<typename Tag, typename Tag::type M>
struct Robber { 
  friend typename Tag::type get(Tag) {
    return M;
  }
};

一个允许多次抢断的公用事业类..

template<typename Tag, typename Member>
struct TagBase {
  typedef Member type;
  friend type get(Tag);
};

声明盗窃意图变为

struct A_f : TagBase<A_f, int A::*> { };
template struct Robber<A_f, &A::a>;

然后窃取数据....

int main() {
  A a(42);
  std::cout << "proof: " << a.*get(A_f()) << std::endl;
}