什么是访问说明符?我应该继承私人,受保护还是公共?

Sis*_*sta 44 c++ private class protected

关于继承的访问修饰符的含义我很困惑.是什么涉及继承之间的区别private,protected以及public关键字?

Alo*_*ave 151

什么是访问说明符?

access specifiers在C++中有3 个类/结构/联合.这些访问说明符定义了如何访问类的成员.当然,类的任何成员都可以在该类中访问(在同一个类的任何成员函数内).继续前进到访问说明符的类型,它们是:

Public - 声明为Public的成员可以通过类的对象从Class外部访问.

受保护 - 声明为受保护的成员只能从类BUT外部访问,只能在派生自它的类中访问.

私人 - 这些成员只能在班级内访问.不允许外部访问.

源代码示例:

class MyClass
{
    public:
        int a;
    protected:
        int b;
    private:
        int c;
};

int main()
{
    MyClass obj;
    obj.a = 10;     //Allowed
    obj.b = 20;     //Not Allowed, gives compiler error
    obj.c = 30;     //Not Allowed, gives compiler error
}
Run Code Online (Sandbox Code Playgroud)

继承和访问说明符

C++中的继承可以是以下类型之一:

  • Private 遗产
  • Public 遗产
  • Protected 遗产

以下是关于以下各项的成员访问规则:

Private除了同一类的成员之外,永远不能从任何地方访问类的第一个也是最重要的规则成员.

公共继承:

Public基类的所有成员都成为Public派生类的成员,基类的
所有Protected成员都成为Protected派生类的成员.

即成员的访问权限没有变化.我们之前讨论过的访问规则将进一步应用于这些成员.

代码示例:

Class Base
{
    public:
        int a;
    protected:
        int b;
    private:
        int c;
};

class Derived:public Base
{
    void doSomething()
    {
        a = 10;  //Allowed 
        b = 20;  //Allowed
        c = 30;  //Not Allowed, Compiler Error
    }
};

int main()
{
    Derived obj;
    obj.a = 10;  //Allowed
    obj.b = 20;  //Not Allowed, Compiler Error
    obj.c = 30;  //Not Allowed, Compiler Error

}
Run Code Online (Sandbox Code Playgroud)

私人继承:

Public基类的所有成员都成为Private派生类的成员,基类的
所有Protected成员都成为Private派生类的成员.

代码示例:

Class Base
{
    public:
      int a;
    protected:
      int b;
    private:
      int c;
};

class Derived:private Base   //Not mentioning private is OK because for classes it  defaults to private 
{
    void doSomething()
    {
        a = 10;  //Allowed 
        b = 20;  //Allowed
        c = 30;  //Not Allowed, Compiler Error
    }
};

class Derived2:public Derived
{
    void doSomethingMore()
    {
        a = 10;  //Not Allowed, Compiler Error, a is private member of Derived now
        b = 20;  //Not Allowed, Compiler Error, b is private member of Derived now
        c = 30;  //Not Allowed, Compiler Error
    }
};

int main()
{
    Derived obj;
    obj.a = 10;  //Not Allowed, Compiler Error
    obj.b = 20;  //Not Allowed, Compiler Error
    obj.c = 30;  //Not Allowed, Compiler Error

}
Run Code Online (Sandbox Code Playgroud)

受保护的继承:

Public基类的所有成员都成为Protected派生类的成员,基类的
所有Protected成员都成为Protected派生类的成员.

代码示例:

Class Base
{
    public:
        int a;
    protected:
        int b;
    private:
        int c;
};

class Derived:protected Base  
{
    void doSomething()
    {
        a = 10;  //Allowed 
        b = 20;  //Allowed
        c = 30;  //Not Allowed, Compiler Error
    }
};

class Derived2:public Derived
{
    void doSomethingMore()
    {
        a = 10;  //Allowed, a is protected member inside Derived & Derived2 is public derivation from Derived, a is now protected member of Derived2
        b = 20;  //Allowed, b is protected member inside Derived & Derived2 is public derivation from Derived, b is now protected member of Derived2
        c = 30;  //Not Allowed, Compiler Error
    }
};

int main()
{
    Derived obj;
    obj.a = 10;  //Not Allowed, Compiler Error
    obj.b = 20;  //Not Allowed, Compiler Error
    obj.c = 30;  //Not Allowed, Compiler Error
}
Run Code Online (Sandbox Code Playgroud)

请记住,相同的访问规则适用于继承层次结构中的类和成员.


重点要注意:

- 访问规范是每个类而不是每个对象

请注意,访问规范C++基于每个类而不是基于每个对象.
一个很好的例子是在复制构造函数或复制赋值操作符函数中,可以访问所传递的对象的所有成员.

- Derived类只能访问其自己的Base类的成员

请考虑以下代码示例:

class Myclass
{ 
    protected: 
       int x; 
}; 

class derived : public Myclass
{
    public: 
        void f( Myclass& obj ) 
        { 
            obj.x = 5; 
        } 
};

int main()
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它给出了编译错误:

prog.cpp:4:错误:'int Myclass :: x'受保护

因为派生类只能访问自己的Base类的成员.请注意,对象obj这里传递是没有办法涉及到derived在它被访问类的功能,它是一个完全不同的对象,因此derived成员函数不能访问它的成员.


什么是friend?如何friend影响访问规范规则?

您可以将函数或类声明为friend另一个类.执行此操作时,访问规范规则不适用于friended类/函数.类或函数可以访问该特定类的所有成员.

那么friend打破封装吗?

不,他们没有,相反,他们增强封装!

friendship用于表示两个实体之间有意的强耦合.
如果两个实体之间存在特殊关系,以便需要访问其他实体privateprotected成员,但您不希望每个人都使用public访问说明符进行访问,那么您应该使用friendship.

  • @Alf:谢谢Alf,我只是希望提问者能够通过答案得知.当我开始时,我必须自己学习,我知道很难这样做,只是努力做到最好.我把它标记为常见问题解答答案但是由于Sbi删除它似乎答案不够好或者它可能不适合FAQ背后的想法. (6认同)
  • 非常感谢您的详细解释.我是C++的新手,这真的帮助我清除了一些概念.对不起,我不能早点回复.我不得不从图书馆回到家里,只是今天早上我看到了你的回复.我现在对访问说明符有了更清楚的了解.再次感谢. (4认同)

Iva*_*iev 5

Scott Meyers在Effective C ++中的解释可能有助于理解何时使用它们:

公共继承应为“是一个关系”建模,而私有继承应为“按条件实现”模型-因此您不必遵循超类的接口,而只是在重用实施。