是否可以使成员变量/函数具有private
的相同访问能力以及它所属的类的可访问性?
在代码中:
class A{
Has-A specifier: //imaginary syntax
int x;
};
class B{
void do_somthing(){
a.x=5; //OK
}
A a;
};
int main(){
A.x=5 // Denied- x is not accessible
}
换句话说,我希望class B
自动为friend
而不向任何与Has-A关系相关的类添加任何代码行。有可能吗?
注意:我知道friendship
将允许它访问其所有私人成员,而不仅仅是x
。如果它可以friendship
在变量/功能级别上,那就太好了。如果没有,全球friendship
也很好。
答案 0 :(得分:2)
我已经使用Apple编译器和GNU ++语言在XCode中测试了以下设置;必须使用设置 - 如果要使用 - 小心。请参阅答案末尾的评论。
假设一个头文件定义了A类,如下所示:
// testprivateA.h:
#ifndef memberpublic
#define memberpublic private:
#endif
class A {
memberpublic
int x;
};
#undef memberpublic
...以及定义B类的单独头文件:
// testprivateB.h:
#include "testprivateA.h"
class B {
public:
void test();
A a;
};
在实施成员函数B::test()
的地方,将memberpublic
定义为public:
:
// testprivateB.cpp:
#define memberpublic public:
#include "testprivateB.h"
void B::test()
{
a.x = 5; // OK
}
在使用类A
的任何其他地方,让memberpublic
保持未定义;访问成员变量A.x
然后产生编译器错误:
// anyOtherFile.cpp:
#include "testprivateB.h"
void testfail()
{
A a;
a.x = 5; // Error: 'x' is a private member of 'A'
}
现在可以询问这种行为是否符合c ++标准。这个问题的答案是 - 实际上并非如此(虽然我花了一些时间才找出原因)。
虽然程序中可能有多个类的定义,但上面的设置与One Definition Rule相矛盾,因为不同的访问说明符会导致不同的标记序列:
程序中可以有多个定义,只要每个定义出现在以下各项的不同翻译单元中:类类型,枚举类型,内联函数与外部链接内联变量与外部链接(从C ++ 17),类模板,非静态函数模板,类模板的静态数据成员,类模板的成员函数,部分模板特化,只要满足以下所有条件: - 每个定义都包含相同的令牌序列(通常显示在同一个头文件中)
仍然可行,但主要问题是access specifiers - cppreference.com中定义的内存布局和访问说明符的连接:
任何数量的访问说明符都可以按任何顺序出现在类中。成员访问说明符可能会影响类布局:非静态数据成员的地址仅保证按声明具有相同访问权限的成员的顺序增加。对于StandardLayoutType,所有非静态数据成员必须具有相同的访问权限。 ...
如果相应类中的所有非静态数据成员具有相同的访问说明符,它仍然可以工作。如果这是一个很好的解决方案,可以决定......