简体   繁体   English

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

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

I am confused about the meaning of access modifiers with respect to inheritance. 我对访问修饰符在继承方面的含义感到困惑。 What is the difference between inheritance involving the private , protected and public keywords? 涉及privateprotectedpublic关键字的继承之间有什么区别?

what are Access Specifiers? 什么是访问说明符?

There are 3 access specifiers for a class/struct/Union in C++. C ++中的class / struct / Union有3个access specifiers 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: 继续介绍访问说明符的类型,它们是:

Public - The members declared as Public are accessible from outside the Class through an object of the class. 公共 -可以通过类的对象从类外部访问声明为“公共”的成员。

Protected - The members declared as Protected are accessible from outside the class BUT only in a class derived from it. 受保护的 -声明为受保护的成员只能从类BUT外部访问, 只能从该类派生。

Private - These members are only accessible from within the class. 私人 -这些成员只能在班级内部访问。 No outside Access is allowed. 不允许外部访问。

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 ++中的继承可以是下列类型之一:

  • Private Inheritance Private继承
  • Public Inheritance Public继承
  • Protected inheritance Protected继承

Here are the member access rules with respect to each of these: 以下是与每个规则有关的成员访问规则:

First and most important rule Private members of a class are never accessible from anywhere except the members of the same class. 第一条也是最重要的规则除同一个类的成员外,从任何地方都无法访问该类的Private成员。

Public Inheritance: 公共继承:

All Public members of the Base Class become Public Members of the derived class & 基类的所有Public成员将成为派生类的Public成员,并且
All Protected members of the Base Class become Protected Members of the Derived Class. 基本类的所有Protected成员都将成为派生类的Protected成员。

ie 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 Public members of the Base Class become Private Members of the Derived class & 所有基础类的Public成员都将成为派生类的Private成员,
All Protected members of the Base Class become Private Members of the Derived Class. 基本类的所有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 Public members of the Base Class become Protected Members of the derived class & 所有基类的Public成员均成为派生类的Protected成员,并且
All Protected members of the Base Class become Protected Members of the Derived Class. 基本类的所有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. 请注意,访问规范C ++是按类而不是按对象工作的。
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. 一个很好的例子是,在复制构造函数或“复制分配”运算符函数中,可以访问正在传递的对象的所有成员。

- 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 obj being passed here is no way related to the derived class function in which it is being accessed, it is an altogether different object and hence derived member function cannot access its members. 请注意,此处传递的对象obj与访问它的derived类函数没有任何关系,它是一个完全不同的对象,因此derived成员函数无法访问其成员。


What is a friend ? 什么是friend How does friend affect access specification rules? friend如何影响访问规范规则?

You can declare a function or class as friend of another class. 您可以将一个函数或类声明为另一个类的friend When you do so the access specification rules do not apply to the friend ed class/function. 这样做时,访问规范规则不适用于friend类/函数。 The class or function can access all the members of that particular class. 该类或函数可以访问该特定类的所有成员。

So do friend s break Encapsulation? friend的包装破裂了吗?

No they don't, On the contrary they enhance Encapsulation! 不,他们没有,相反,它们增强了封装!

friend ship is used to indicate a intentional strong coupling between two entities. friend飞船用于表示两个实体之间的故意强耦合
If there exists a special relationship between two entities such that one needs access to others private or protected members but You do not want everyone to have access by using the public access specifier then you should use friend ship. 如果两个实体之间存在特殊关系,使得一个实体需要访问其他privateprotected成员,但是您不希望每个人都可以使用public访问说明符进行访问,则应该使用friend

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM