【问题标题】:public, protected, private公共、受保护、私有
【发布时间】:2010-08-02 14:04:35
【问题描述】:

看看这段代码:

#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 的子类。

【问题讨论】:

  • 不,B 不是 A 的子类。如果您使用公共继承,它会是。
  • Here 解释了它的工作原理。
  • 为什么?私有继承意味着所有继承的字段和方法都将变为私有,因此它们只能在派生类中访问。
  • +1,因为它看起来像一个初学者的问题,但是很多答案或cmets都是错误的。我做了一个测试:私有或公共继承没有区别。

标签: c++ access-modifiers


【解决方案1】:

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

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

苹果无权访问橙子的内部,即使它们都是水果。

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);
}

【讨论】:

  • 那是什么意思是网上的解释有一半是错误的?因为他们说子类可以访问超类的受保护成员,这是不真实的。它可以访问它们,因为它拥有它们,对吗?因此受保护意味着它们可以复制到与公共相同的子类,但不能从类外部访问。对吗?
  • 你的答案是对的,但是你根本不需要apple类。 (正如您所说,编译器抱怨 Orange 类中的受保护访问)。只是说:橙子不能改变另一种水果的内部结构——即使它也是橙子。
  • 一个 Orange 可以访问另一个 Orange 如果它认为是 Orange 的受保护内部结构。 - 是的,在示例中,如果 evil_function 传递了 Orange 的实例而不是 Apple,它仍然是编译错误,因为不能保证总是传递 Oranges。如果 evil_function 接受了 Orange&amp; 而不是 Fruit&amp; ,那么它修改参数的受保护成员是合法的。
【解决方案2】:

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

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

【讨论】:

  • Protected 表示从 A 和 A 的子类访问。B 是 A 的子类。
  • @l245c4l:B 不是 A 的子类,因为您使用的是私有继承,而不是公共继承。公共继承意味着“is-a”,私有继承意味着“is-implemented-in-terms-of”。
  • 公有/私有继承是红耳。没有对象间访问权限,每个对象仅将其公共接口暴露给其他对象(无论是什么类)。友谊是颠覆访问说明符的唯一途径。注意:X 类是它自己的朋友。
【解决方案3】:

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

#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!!!!
}

谢谢!

【讨论】:

    猜你喜欢
    • 2023-04-08
    • 2011-06-19
    • 2017-12-19
    • 1970-01-01
    • 2019-08-24
    • 2021-03-19
    • 2019-02-14
    • 2012-06-02
    • 2011-05-20
    相关资源
    最近更新 更多