公共的,受保护的,私有的

3

看一下这段代码:

#include <iostream>

using namespace std;

class A
{
private:
    int privatefield;
protected:
    int protectedfield;
public:
    int publicfield;
};

class B: private A
{
private:
    A a;
public:
    void test()
    {
        cout << this->publicfield << this->protectedfield << endl;
    }
    void test2()
    {
        cout << a.publicfield << a.protectedfield << endl;
    }
};

int main()
{
    B b;
    b.test();
    b.test2();
    return 0;
}

B可以访问this->protectedfield但不能访问a.protectedfield。为什么? B是A的子类。

4
不,B不是A的子类。如果使用公共继承,则会成为子类。 - anon
这里有一个关于C++中私有、公有和保护继承的解释。 - Kirill V. Lyadvinsky
为什么?私有继承意味着所有继承的字段和方法都将变为私有,因此只能在派生类中访问。 - l245c4l
+1,因为它看起来像一个初学者的问题,但是很多答案或评论都是错误的。我进行了测试:私有或公有继承没有区别。 - IanH
3个回答

3

B只能访问自己或类型为B的其他对象中的受保护字段(如果它将它们视为B,则可能包括从B派生的对象)。

B无法访问同一继承树中任何其他不相关对象的受保护字段。

即使Apple和Orange都是水果,Apple也无权访问Orange的内部内容。

class Fruit
{
    protected: int sweetness;
};

class Apple: public Fruit
{
    public: Apple() { this->sweetness = 100; }
};

class Orange: public Fruit
{
public:
    void evil_function(Fruit& f)
    {
        f.sweetness = -100;  //doesn't compile!!
    }
};

int main()
{
    Apple apple;
    Orange orange;
    orange.evil_function(apple);
}

那么这意味着互联网上一半的解释都是错误的?因为它们说子类可以访问超类的受保护成员,这是不正确的。它可以访问它们,因为它本身就拥有它们,对吧?所以受保护的意思是它们可以被复制到子类中,就像公共成员一样,但不能从类外部访问。这正确吗? - l245c4l
你的答案是正确的,但你根本不需要苹果类。 (正如你所说,编译器抱怨橙色类的受保护访问)。 只需说:橙子不能更改另一种水果的内部 - 即使它也是橙色的。 - IanH
1
一个橙子可以访问另一个橙子的受保护内部,如果它将其视为橙子。- 是的,在这个例子中,如果evil_function接收到一个Orange实例而不是Apple,它仍然会出现编译错误,因为没有保证橙子总是被传递。如果evil_function接受一个Orange&而不是Fruit&,它就可以合法地修改参数的受保护成员。 - UncleBens

3

this->protectedfield: B继承自A,这意味着protectedfield现在是它自己的属性,因此它可以访问它。

a.protectedfield: a是类B的成员,该成员具有受保护的变量protectedfield。B无法访问它,因为protected意味着只能从A内部访问。


Protected 意味着只有 A 和 A 的子类可以访问,而 B 是 A 的子类。 - l245c4l
@l245c4l:B不是A的子类,因为您使用的是私有继承,而不是公有继承。公有继承意味着“是一个”,私有继承意味着“以某种方式实现”。 - TheJuice
1
公共/私有继承是一个误导。每个对象都只向其他对象(无论类别如何)公开其公共接口,没有对象间的访问特权。友元是颠覆访问限定符的唯一方法。注意:类X是自己的朋友。 - Martin York

0

让我们将整个代码分解成小部分。复制并粘贴这两个代码,尝试编译!

#include <iostream>
using namespace std;
class A
{
private:
    int privatefield;
protected:
    int protectedfield;
public:
    int publicfield;
};

int main()
{
    A a;
    cout<<a.publicfield;
    cout<<a.privatefield;/////not possible ! private data can not be seen by an object of that class
    cout<<a.protectedfield;////again not possible. protected data is like privete data except it can be inherited by another.If inherited as private then they are private,if as protected then protected and if as public then also protected.
}

现在B以私有方式继承类A

#include <iostream>

using namespace std;

class A
{
private:
    int privatefield;
protected:
    int protectedfield;
public:
    int publicfield;
};

class B: private A
{
private:
    A a;
public:
    void test()
    {
        cout << this->publicfield << this->protectedfield << endl;
    }
    void test2()
    {
        cout << a.publicfield << endl;
    }
};
int main()
{
    /*Now B will have both public and protected data as private!!!!
    That means
     B now looks like this class


     Class B
     {  

        private:
        int protectedfield;
        int publicfield;
     }

     As we have discussed private/protected data can not be accessed by object of the class
     so you you can not do things like this

     B b;
     b.protectedfield; or b.publicfield;

     */
    B b;
    b.privatefield;////Error !!!
    b.protectedfield/////error!!!!
}

谢谢!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接