C++ 什么是访问说明符?我应该继承私有的、受保护的还是公共的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5447498/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:11:38  来源:igfitidea点击:

What are access specifiers? Should I inherit with private, protected or public?

c++classprivateprotected

提问by Sista

I am confused about the meaning of access modifiers with respect to inheritance. What is the difference between inheritance involving the private, protectedand publickeywords?

我对访问修饰符在继承方面的含义感到困惑。涉及private,protectedpublic关键字的继承之间有什么区别?

回答by Alok Save

what are Access Specifiers?

什么是访问说明符?

There are 3 access specifiersfor a class/struct/Union in C++. These access specifiers define how the members of the class can be accessed. Of course, any member of a class is accessible within that class(Inside any member function of that same class). Moving ahead to type of access specifiers, they are:

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

Public- The members declared as Public are accessible from outside the Class through an object of the class.

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

Protected- The members declared as Protected are accessible from outside the class BUTonly in a class derived from it.

Protected- 声明为 Protected 的成员可以从类外部访问,只能在派生自它的类中访问。

Private- These members are only accessible from within the class. No outside Access is allowed.

Private- 这些成员只能从类内部访问。不允许外部访问。

An Source Code Example:

源代码示例:

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
}


Inheritance and Access Specifiers

继承和访问说明符

Inheritance in C++ can be one of the following types:

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

  • PrivateInheritance
  • PublicInheritance
  • Protectedinheritance
  • Private遗产
  • Public遗产
  • Protected遗产

Here are the member access rules with respect to each of these:

以下是与这些相关的成员访问规则:

First and most important rule Privatemembers of a class are never accessible from anywhere except the members of the same class.

Private除了同一类的成员之外,从任何地方都无法访问类的第一个也是最重要的规则成员。

Public Inheritance:

公共继承:

All Publicmembers of the Base Class become PublicMembers of the derived class &
All Protectedmembers of the Base Class become ProtectedMembers of the Derived Class.

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

i.e. No change in the Access of the members. The access rules we discussed before are further then applied to these members.

即成员的访问没有变化。我们之前讨论的访问规则会进一步应用于这些成员。

Code Example:

代码示例:

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

}

Private Inheritance:

私人继承:

All Publicmembers of the Base Class become PrivateMembers of the Derived class &
All Protectedmembers of the Base Class become PrivateMembers of the Derived Class.

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

An code Example:

代码示例:

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

}

Protected Inheritance:

受保护的继承:

All Publicmembers of the Base Class become ProtectedMembers of the derived class &
All Protectedmembers of the Base Class become ProtectedMembers of the Derived Class.

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

A Code Example:

代码示例:

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
}

Remember the same access rules apply to the classes and members down the inheritance hierarchy.

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



Important points to note:

需要注意的要点:

- Access Specification is per-Class not per-Object

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

Note that the access specification C++ work on per-Class basis and not per-object basis.
A good example of this is that in a copy constructor or Copy Assignment operator function, all the members of the object being passed can be accessed.

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

- A Derived class can only access members of its own Base class

- 派生类只能访问其自身基类的成员

Consider the following code example:

考虑以下代码示例

class Myclass
{ 
    protected: 
       int x; 
}; 

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

int main()
{
    return 0;
}

It gives an compilation error:

它给出了一个编译错误:

prog.cpp:4: error: ‘int Myclass::x' is protected

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

Because the derived class can only access members of its own Base Class. Note that the object objbeing passed here is no way related to the derivedclass function in which it is being accessed, it is an altogether different object and hence derivedmember function cannot access its members.

因为派生类只能访问它自己的 Base Class 的成员。请注意,obj这里传递的对象与derived访问它的类函数没有任何关系,它是一个完全不同的对象,因此derived成员函数无法访问其成员。



What is a friend? How does friendaffect access specification rules?

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

You can declare a function or class as friendof another class. When you do so the access specification rules do not apply to the friended class/function. The class or function can access all the members of that particular class.

您可以将函数或类声明为friend另一个类。当您这样做时,访问规范规则不适用于friended 类/函数。类或函数可以访问该特定类的所有成员。

So do friends break Encapsulation?

那么friends会破坏封装吗?

No they don't, On the contrary they enhance Encapsulation!

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

friendship is used to indicate a intentional strong couplingbetween two entities.
If there exists a special relationship between two entities such that one needs access to others privateor protectedmembers but You do not want everyoneto have access by using the publicaccess specifier then you should use friendship.

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

回答by Ivan Vergiliev

The explanation from Scott Meyers in Effective C++ might help understand when to use them:

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

Public inheritance should model "is-a relationship," whereas private inheritance should be used for "is-implemented-in-terms-of" - so you don't have to adhere to the interface of the superclass, you're just reusing the implementation.

公共继承应该建模“is-a 关系”,而私有继承应该用于“is-implemented-in-terms-of”——所以你不必坚持超类的接口,你只是重用实施。