天天看点

C++中的private, public, protected

0.概述

数据隐藏是C++面向对象编程的重要特征之一,它允许我们隐藏对象内部细节即数据成员,防止程序的函数直接访问一个类对象的内部表示、数据成员和成员函数。

对类成员函数的访问限制由访问修饰符指定。访问修饰符在 C++ 中也称为可见性模式,private、public 和 protected 都是可见性模式的类型。我们将在本文接下来的部分中详细讨论它们中的每一个。

C++中的private, public, protected

可见性模式让我们知道基类将如何被派生类继承,以及基类的哪些成员将被派生类获取和访问。给出名称可见性模式或访问说明符,因为它们用于定义类成员的可访问性和可见性级别。

当派生类的对象可以使用基类中的成员函数时,访问说明符主要用于继承。从基类派生子类时使用访问说明符的一般语法是:

class Base {
// content of the base class 
};

class Derived: access_specifier Base {
// content of the child's class
};
           

在上面的代码中,我们有一个基类Base和一个派生类Derived,以及access_specifier告诉我们基类的哪些成员将被派生类获取和访问。

C++ 中的一个类可以有多个public、protected或private部分。我们可以在下面的代码中看到我们如何在类中使用可见性模式:

class base {
public:
   // public members go here
protected:
   // protected members go here
private:
   // private members go here
};
           

在上面的代码中,我们有一个基类base,有多个部分被访问说明符分开。

注意:如果未指定可见性模式,则默认情况下会考虑private模式。

1.private成员

在private可见性模式下,当我们从父类继承子类时,那么基类的所有成员(public、private和protected成员)在派生类中都会变成private。

这些成员在派生类之外的访问是有限制的,只能被派生类的成员函数或友元函数访问。

下面的框图可以说明当派生类的访问方式为private时,基类的数据成员是如何被继承的。

C++中的private, public, protected

从上图中可以看出,private变量a在派生类中是不可访问的,因为它在基类内部是private类型,所以只能被基类内部的成员函数访问。基类的public变量c和protected变量b在派生类中会变成private,只能被派生类的成员函数访问。

借助一个非常基本的现实生活示例,我们可以了解何时需要哪个访问说明符,假设在任何社交媒体应用程序上,你想更新状态,但你对谁可以看到这个有一些要求和限制互联网上的地位。所以,如果你希望没有人看到这个状态或者它应该“只对我可见”,那么这意味着你正在遵循“private访问说明符”的概念。

1.1例子

让我们看一个例子来理解private可见性模式的概念及其提供的限制:

class Parent
{
    private:
     int x1;
    protected:
     int x2;
    public:
     int x3;
};
class Child: private Parent
{

};
           

在上面的代码中,由于可见模式是private,所以,基类的所有成员在派生类中都变成了private。当派生类的对象试图访问派生类之外的这些成员时,将抛出该错误。

现在,让我们再用一个 C++ 程序来演示当基类的对象试图访问类外的private数据成员x时private访问说明符的作用。

class base
{  
    // private data member
    private:
        int x;
    // public member function   
    public:   
        void  fun()
        {   
            // member function of the base class can access private data member
            return 2 * x;
        }
     
};
 
// main function
int main()
{  
    // creating object of the class
    base obj;
     
    // trying to access private data members directly outside the class
    obj.x = 78;
    cout << obj.fun() << endl;
}
           

上述程序的输出将是编译时错误,因为我们不允许直接从类外部访问类成员的private数据。

但是,我们可以通过调用基类的public成员函数来间接访问基类的private数据成员。

1.2辅助功能

private模式的可访问性可以总结如下:

Accessibility Private mode
Same class Yes
Derived class No
Other class No
Anywhere in the program No

在 private 访问说明符下定义的成员只能在同一个类中访问,它们在派生类或程序的任何其他类中是不可访问的。

2.public成员

在public可见性模式下,当我们从父类继承子类时,基类的public成员、private成员和protected成员在派生类中也分别保持public成员、private成员和protected成员。public可见性模式保留了父类所有成员的可访问性。

父类的public成员可由子类和所有其他类访问。基类的protected成员只能在派生类及其继承类中访问。但是,子类无法访问private成员。

下面的框图可以说明派生类访问方式为public时,基类的数据成员是如何被继承的。

C++中的private, public, protected

从上图可以看出,private变量a在派生类中是不可访问的,因为它是private类型,所以只能被基类的成员函数访问。public变量a将保持public状态,子类和所有其他类都可以访问。基类的protected变量b将在派生类中保持protected状态,并且只能在派生类及其继承类中访问。

回到现实生活中更新任何社交媒体应用程序状态的例子,我们在上面已经提到,假设你希望互联网上的任何人都可以看到你的状态,那么,这意味着你遵循“公开”的概念访问说明符”。

2.1例子

让我们看一个例子来理解public可见性模式的概念及其提供的限制:

class Parent
{
    private:
     int x1;
    protected:
     int x2;
    public:
     int x3;
};
class Child: public Parent
{

};
           

上述代码中,保护变量x2将从Parent类继承,并在Child类及其继承类中访问,同理,public变量x3将从Parent类继承,并在Child和其它类中可以访问,但private变量 x1 将无法在 Child 类中访问。

现在,让我们再用一个 C++ 程序来演示当基类的对象试图在 main() 函数中访问类外部的public数据成员x时public访问说明符的工作。

class base
{
    public:
        int x;
        void  fun()
        {
            return 2 * x;
        }
     
};
 
// main function
int main()
{
    // creating object of the derived class
    base obj;
     
    // accessing public data members outside class
    obj.x = 9;
     
    cout << obj.x << endl;
    cout << obj.fun();
}

           

上述程序的输出将是:

9
18
           

在上面的程序中,数据成员x被声明为public,因此它可以在任何类中访问,也可以从类外访问。

2.2辅助功能

public模式的可访问性可以总结如下:

Accessibility Public mode
Same class Yes
Derived class Yes
Other class Yes
Anywhere in the program Yes

在 public 访问说明符下定义的成员在任何地方都可以访问,在同一个类中,在派生类中,在任何其他类中,甚至在类之外。

3.protected成员

在protected可见性模式下,当我们从父类继承子类时,那么基类的所有成员都会成为派生类的protected成员。

因此,这些成员现在只能由派生类及其成员函数访问。这些成员也可以被继承,并将可供该派生类的继承子类访问。

下面的框图可以说明在保护派生类访问方式的情况下,基类的数据成员是如何被继承的。

C++中的private, public, protected

从上图可以看出,private变量a在派生类中是不可访问的,因为它是private类型,所以只能被基类的成员函数访问。public变量a将在派生类中受到保护,并且只能由该派生类的继承子类访问。基类的protected变量b将在派生类中保持protected状态,并且只能在派生类及其继承类中访问。

再一次,回到现实生活中更新任何社交媒体应用程序状态的例子,我们在上面假设,现在,如果你希望你的状态只对你的朋友和你朋友的朋友可见,那么,意味着你遵循“protected访问说明符”的概念。

3.1例子

让我们看一个例子来理解protected可见性模式的概念及其提供的限制:

class Parent
{
    private:
     int x1;
    protected:
     int x2;
    public:
     int x3;
};
class Child: protected Parent
{

};
           

在上面的代码中,由于可见性模式被保护,Parent类的protected和public成员将成为Child类的protected成员。

protected变量x2将从Parent类继承,在Child类中可以访问,同理,public变量x3作为protected成员从父类继承,在Child类中可以访问,但是private变量x1 在 Child 类中将不可访问。

现在,让我们再用一个 C++ 程序来演示当基类的对象试图在 main() 函数中访问类外部的protected数据成员x时protected访问说明符的工作原理。

class base
{
    protected:
        int x;
        void  fun()
        {
            return 2 * x;
        }
     
};
 
// main function
int main()
{
    // creating object of the derived class
    base obj;
     
    // accessing public data members outside class
    obj.x = 9;
     
    cout << obj.x << endl;
    cout << obj.fun();
}

           

上述程序的输出将是:

9
18
           

在上面的程序中,数据成员x被声明为protected,因此它可以被基类的任何子类(派生类)访问。

3.2辅助功能

保护模式的可访问性可以总结如下:

Accessibility Protected mode
Same class Yes
Derived class Yes
Inherited subclasses of the derived class Yes
Other class No
Anywhere in the program No

在protected访问说明符下定义的成员可在派生类及其继承类中访问。

4.对比与总结

C++ 中 Private、Public 和 Protected 的区别

Private Public Protected
声明为private类成员只能由基类内部的函数访问。 可以从任何地方访问声明为public的类成员。 声明为protected类成员可以在基类及其派生类中访问。
private成员使用关键字private后跟冒号 (:) 字符来声明。 public成员使用关键字public后跟冒号 (:) 字符来声明。 protected成员使用关键字protected后跟冒号 (:) 字符来声明。
private成员能被子类继承,但不能被子类的对象直接访问。 public成员可以在子类中被继承并被直接访问。 protected成员可以在子类中被继承并访问。
它为其数据成员提供高安全性。 它不为其数据提供任何类型的安全性。 它提供的安全性低于private访问说明符。
可以在友元功能的帮助下访问private成员。 public成员可以在有或没有友元功能的帮助下访问。 protected成员不能通过友元函数访问,它们在类之外是不可访问的,但它们可以被该类的任何子类(派生类),包括派生类及派生类的子类访问。

我们可以总结一下C++中对以上三种可见性模式的理解:

class Base {
  public:
    int x;
  protected:
    int y;
  private:
    int z;
    
};

class PublicDerived: public Base {
  // x is public and is accessible in PublicDerived class
  // y is protected and is accessible in PublicDerived class
  // z is not accessible from PublicDerived, as it is a private member of the base class
    
};

class ProtectedDerived: protected Base {
  // x is protected and is accessible in ProtectedDerived class
  // y is protected and is accessible in ProtectedDerived class
  // z is not accessible from ProtectedDerived, as it is a private member of the base class
    
};

class PrivateDerived: private Base {
  // x is private and is only accessible by the member functions of the PrivateDerived class
  // y is private and is only accessible by the member functions of the PrivateDerived class
  // z is not accessible from PrivateDerived, as it is a private member of the base class
    
};
           
C++中的private, public, protected

5.结论

  • 访问说明符已用于确定该类之外的类成员(数据成员和成员函数)的可用性。
  • 在继承中,知道派生类的对象何时可以使用基类中的成员函数很重要,这称为可访问性,访问说明符用于确定这一点。
  • private、public 和protected 都是C++ 中访问说明符的类型。如果未提及或指定可见性模式,则默认情况下会考虑private模式。
  • 当类的成员被声明为 public 时,就可以从任何地方访问它们。
  • 当类中的成员被声明为protected时,它们就可以在基类和派生类中访问。
  • 当类中的成员被声明为private时,它们只能被基类的成员和友元函数访问。
  • 与public和protected访问说明符相比,private访问说明符为其数据成员提供更多的安全性。
  • 将你的类属性声明为private(尽可能经常)被认为是一种很好的做法,因为这将有助于提高数据安全性。
  • 访问修饰符主要用于数据隐藏和封装,因为它们可以帮助我们控制程序的哪一部分可以访问类的成员。这样就可以防止滥用数据。