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

2021-12-01 00:00:00 class private protected c++

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

解决方案

什么是访问说明符?

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

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

Protected - 声明为 Protected 的成员只能在从它派生的类中BUT的外部访问.

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

源代码示例:

class MyClass{民众:一个;受保护:国际b;私人的:国际 c;};int main(){MyClass obj;目标.a = 10;//允许obj.b = 20;//不允许,给出编译错误obj.c = 30;//不允许,给出编译错误}

<小时>

继承和访问说明符

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

  • 私有继承
  • 公共继承
  • 受保护继承

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

<块引用>

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

公共继承:

<块引用>

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

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

代码示例:

类库{民众:一个;受保护:国际b;私人的:国际 c;};派生类:公共基础{void doSomething(){一 = 10;//允许b = 20;//允许c = 30;//不允许,编译错误}};int main(){派生对象;目标.a = 10;//允许obj.b = 20;//不允许,编译错误obj.c = 30;//不允许,编译错误}

私有继承:

<块引用>

基类的所有公共成员成为派生类的私有成员&
基类的所有 Protected 成员都成为派生类的 Private 成员.

代码示例:

类库{民众:一个;受保护:国际b;私人的:国际 c;};class Derived:private Base//不提private也可以,因为类默认是private{void doSomething(){一 = 10;//允许b = 20;//允许c = 30;//不允许,编译错误}};类派生2:公共派生{void doSomethingMore(){一 = 10;//不允许,编译器错误,a现在是Derived的私有成员b = 20;//不允许,编译错误,b现在是Derived的私有成员c = 30;//不允许,编译错误}};int main(){派生对象;目标.a = 10;//不允许,编译错误obj.b = 20;//不允许,编译错误obj.c = 30;//不允许,编译错误}

受保护的继承:

<块引用>

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

代码示例:

类库{民众:一个;受保护:国际b;私人的:国际 c;};派生类:受保护的基类{void doSomething(){一 = 10;//允许b = 20;//允许c = 30;//不允许,编译错误}};类派生2:公共派生{void doSomethingMore(){一 = 10;//允许,派生&里面的a是受保护的成员Derived2 是 Derived 的公共派生,现在是 Derived2 的受保护成员b = 20;//允许,b是Derived &里面的受保护成员Derived2 是 Derived 的公共派生,b 现在是 Derived2 的受保护成员c = 30;//不允许,编译错误}};int main(){派生对象;目标.a = 10;//不允许,编译错误obj.b = 20;//不允许,编译错误obj.c = 30;//不允许,编译错误}

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

<小时>

注意事项:

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

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

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

考虑以下代码示例:

class Myclass{受保护:整数 x;};派生类:公共Myclass{民众:void f( Myclass& obj ){obj.x = 5;}};int main(){返回0;}

它给出了一个编译错误:

<块引用>

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

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

<小时>

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

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

<块引用>

那么friend会破坏封装吗?

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

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

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?

解决方案

what are Access Specifiers?

There are 3 access specifiers for 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:

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.

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:

  • Private Inheritance
  • Public Inheritance
  • Protected inheritance

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.

Public Inheritance:

All Public members of the Base Class become Public Members of the derived class &
All Protected members of the Base Class become Protected Members of the Derived Class.

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 Public members of the Base Class become Private Members of the Derived class &
All Protected members of the Base Class become Private Members of the Derived Class.

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 &
All Protected members of the Base Class become Protected Members of the Derived Class.

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.

- 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

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.


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

You can declare a function or class as friend of 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.

So do friends break Encapsulation?

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

friendship is used to indicate a intentional strong coupling between two entities.
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 friendship.

相关文章