【问题标题】:Access specifier for Has-A relationshipHas-A 关系的访问说明符
【发布时间】:2016-12-15 18:01:55
【问题描述】:

是否有可能使成员变量/函数具有与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 也不错。

【问题讨论】:

  • 不,这是不可能的。向c++ standards commitee发送更清晰的提案。
  • A::x受保护,并从A继承B
  • @πάνταῥεῖ 我确定您有理由将其写为评论而不是答案?如果问题是标准委员会提案的副本,那一定是一个很好的问题!
  • @JackDeeth 好吧,我不确定你是否已经可以使用一些模板元编程技巧来实现类似的目标,但实际上我懒得研究这个。
  • 一种方法是编写自定义预处理器,如stackoverflow.com/questions/3545875/custom-gcc-preprocessor 中所述。

标签: c++


【解决方案1】:

我已经使用苹果编译器和 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,所有非静态数据成员必须具有相同的访问权限。 ...

如果相应类中的所有非静态数据成员具有相同的访问说明符,它仍然可以工作。如果这是一个好的解决方案,人们可​​能会决定......

【讨论】:

  • 嗯...我很想听听比我更了解 C++ 标准的人的意见,了解这种行为是否标准化。
  • @Silvio:我花了更多时间调查标准一致性。结果表明我提出的解决方案不符合标准,它“可能”仅适用于特定情况。尽管如此,我还是保留了解决方案,并在答案的最后讨论了这个话题。
猜你喜欢
  • 2014-01-11
  • 1970-01-01
  • 2011-01-31
  • 2021-11-02
  • 2016-08-11
  • 1970-01-01
  • 2011-01-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多