如何通过派生类访问基类的受保护成员?

时间:2019-04-05 10:00:33

标签: c++

我正在尝试一些有关继承的程序,结果发现以下内容引起了错误,但我并不真正了解其原理。

#include <iostream>

using namespace std;

class Base {
protected:
    int x = 0;
};

class Derived: public Base {

    // OK: access protected member via this
    void g() { cout<<x; } 

    // OK: access protected member of other Derived
    void h(Derived& d) { cout<<d.x; } 

    // FAIL: access Base class's protected member, why?
    void f(Base& b) { cout<<b.x; } 
};

int main() {}

我希望Derived类可以访问基类的公共或受保护的数据成员和成员函数。

但是它没有按照我的想法工作,有人可以帮助我阐明我的概念吗?

4 个答案:

答案 0 :(得分:2)

void f(Base& b) {cout<<b.x;}

在这里,您尝试访问其他类的受保护成员。您也共享相同的基类并不重要。 (仍在寻找来源)

void g() {cout<<x;}

在此示例中,您将拥有自己的私人成员。 (基类的受保护成员在派生类中继承和保护)

void h(Derived& d) {cout<<d.x;}

在这里您正在访问同一班的私人成员。但有关更多信息,请参见以下帖子:Access private elements of object of same class

答案 1 :(得分:1)

没有比您已经发现的更多的东西了。派生实例可以访问其受保护成员以及其他派生实例的成员,但不能访问基类实例的成员。为什么?因为这就是protected按照定义的工作方式。

有关更多详细信息,请参考cppreference(强调我的观点):

  

只能访问基类的受保护成员

     

1)由Base的成员和朋友

     

2)由成员和朋友(直到   C ++ 17)源自Base的任何类,,但仅适用于在   从Base(包括此)派生的类型的对象

答案 2 :(得分:1)

来自this documentation

  

只能访问基类的受保护成员

     
      
  1. 由Base的成员和朋友

         

    这不是您的情况

  2.   
  3. 由成员和朋友(直到   C ++ 17)从Base派生的任何类,但仅当在   从Base(包括此)派生的类型的对象

         

    这是您的情况,但是参数b不是这种派生类型

  4.   

受保护成员访问的原因是允许基类定义供派生类使用的接口。 与允许每个不同的派生类型对每个基类对象有特殊访问权限不同。

答案 3 :(得分:0)

您问题中的代码似乎像cppreference网站上的示例,在代码注释中我们可以看到关于该限制的很好的解释:

struct Base {
 protected:
   int i;
 private:
   void g(Base& b, struct Derived& d);
};

struct Derived : Base {
   void f(Base& b, Derived& d) // member function of a derived class
   {
      ++d.i; // okay: the type of d is Derived
      ++i; // okay: the type of the implied '*this' is Derived
//    ++b.i; // error: can't access a protected member through Base
//             (Otherwise it would be possible to change other derived classes, 
//                  like a hypothetical Derived2, base implementation)
    }
};

所以,如果您有

class Derived2: public Base {
};

不允许Derived类访问Derived2受保护的属性,因为它不是Derived2的子级。 protected的目的不是允许兄弟姐妹,而是允许孩子对成员进行访问。

标准中的全部详细信息: