为什么派生类d的对象不能调用基类的受保护成员函数?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么派生类d的对象不能调用基类的受保护成员函数?相关的知识,希望对你有一定的参考价值。

这里派生类d的对象无法调用类库的受保护成员函数。

#include <iostream>

using namespace std;

class base
{
protected:
    int i,j;
    void setij(int a,int b)
    {
        i=a;
        j=b;
    }
    void showij()
    {
        cout<<i<<" "<<j<<endl;
    }
};

class derived : protected base
{
    int k;
public:
    void show()
    {
        base b;
        b.setij(10,20);
        b.showij();
    }

};

int main()
{
    base b;
    derived d;
    d.setij(3,4);
    d.showij();
    d.show();
    return 0;
}

我希望输出为10 20,但是编译器显示错误。

答案

您使用了protected继承。问题不在于派生对象不能访问基础的受保护方法,而是问题是您不能从derived的外部访问基础方法。

如果您不知道受保护的继承意味着什么,您可以阅读例如此处Difference between private, public, and protected inheritance

我怀疑您想在这里使用protected继承(为什么?)。将其更改为public继承,您的代码应该可以:

class derived : public base ...

PS:错误消息应该告诉您实际的问题是什么(尽管以一种隐秘的方式)。请下次将其包含在问题中。如果您听不懂,也许其他人也会。

另一答案

此代码有lot错误。即使将类derived的继承从protected更改为public,仍然存在以下问题:

  1. 在类derived中,语句b.setij(10,20);b.showij();仍会生成编译器错误。参见Why can't a derived class call protected member function in this code?获得很好的解释。简短的解释:方法只能在最初为其调用对象的基类中调用受保护的方法。

  2. 函数main将无法调用d.setij(3,4);d.showij();,因为它们是base类中的受保护方法。

这应该运行:

#include <iostream>

using namespace std;

class base
{
protected:
    int i,j;
    void setij(int a,int b)
    {
        i=a;
        j=b;
    }
    void showij()
    {
        cout<<i<<" "<<j<<endl;
    }
};

class derived : public base
{
    int k;
public:
    void show()
    {
        this->setij(10,20);
        this->showij();
    }

};

int main()
{
    derived d;
    d.show();
    return 0;
}

以上是关于为什么派生类d的对象不能调用基类的受保护成员函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Derived 内部调用 Base 实例中的受保护成员函数?

C#:基类中的受保护方法;无法使用来自另一个类的派生类对象进行访问[重复]

C++ 派生模板类:访问实例的受保护成员

protected 成员与派生类

在派生类中使用来自虚拟基类的受保护 ctor

从派生类访问基类中的受保护成员