无法在派生类中访问基类的受保护成员

时间:2012-09-04 20:32:26

标签: c++ protected access-control

我有以下代码:

struct A {
protected:
    A() {}

    A* a;
};

struct B : A {
protected:
    B() { b.a = &b; }

    A b;
};

奇怪的是没有编译。罪魁祸首是b.a = &b;任务:GCC和clang都抱怨A()受到保护,这应该不是问题,因为B继承了A.我进入标准的哪个黑暗角落?

4 个答案:

答案 0 :(得分:21)

protected的含义是派生类型可以访问其自己的基础的成员,而不能访问任何随机对象 * 。在您的情况下,您需要尝试修改b无法控制的成员(即您可以设置this->a,但不能设置b.a

如果你感兴趣的话,有一个hack可以让它工作,但更好的解决方案是重构代码而不依赖于hacks。例如,您可以在A中提供一个构造函数,该构造函数将A*作为参数(此构造函数应该是公共的),然后在B的初始化列表中初始化它:

A::A( A* p ) : a(p) {}
B::B() : b(&b) {}

* protected授予您在自己类型的任何实例中访问基本成员或从您自己的类型派生的权限。

答案 1 :(得分:2)

这里实际上有两个不同的问题。

第一个是该行不仅仅进行赋值,而是尝试初始化基类(工作正常)和成员b。要创建b成员,需要构建它,作为成员需要public访问构造函数,而它没有。

然后,分配也无法访问b的非公开成员,因为它不是B类型,而是键入A

请注意,protected表示您只能通过A对象(或儿童)访问B 的部分内容。

在这种情况下,请告诉我们您的真正问题,我们可以尝试帮助解决它。从同一类型继承和创作是一种设计气味。

答案 2 :(得分:0)

我测试的所有编译器都抱怨了几件事情,特别是受保护的构造函数会出现问题,即使删除了赋值语句。

您无法访问您派生的任何类型实例的protected成员。这个问题在11.4p1的例子中得到澄清。

class B {
protected:
  int i;
  static int j;
};

class D1 : public B {
};

class D2 : public B {
  void mem(B*, D1*);
};

void D2::mem(B* pb, D1* p1) {
  pb->i = 1; // ill-formed
  p1->i = 2; // ill-formed
  // ...
}

答案 3 :(得分:0)

这似乎是C ++语言的一个很大的局限。你会如何解决这样的问题:

class Node
{
public:
 void Save();
protected:
 virtual void SaveState(int type) = 0;
};

class BinaryNode : public Node
{
protected:
 Node *left;
 Node *right;

 virtual void SaveState(int type) override
 {
    left->SaveState(type);
    right->SaveState(type);
 }
};

在此示例中,我不希望方法SaveStateNode层次结构之外可见。只有方法Save应为public