0.概述
数据隐藏是C++面向对象编程的重要特征之一,它允许我们隐藏对象内部细节即数据成员,防止程序的函数直接访问一个类对象的内部表示、数据成员和成员函数。
对类成员函数的访问限制由访问修饰符指定。访问修饰符在 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时,基类的数据成员是如何被继承的。
从上图中可以看出,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时,基类的数据成员是如何被继承的。
从上图可以看出,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成员。
因此,这些成员现在只能由派生类及其成员函数访问。这些成员也可以被继承,并将可供该派生类的继承子类访问。
下面的框图可以说明在保护派生类访问方式的情况下,基类的数据成员是如何被继承的。
从上图可以看出,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
};
5.结论
- 访问说明符已用于确定该类之外的类成员(数据成员和成员函数)的可用性。
- 在继承中,知道派生类的对象何时可以使用基类中的成员函数很重要,这称为可访问性,访问说明符用于确定这一点。
- private、public 和protected 都是C++ 中访问说明符的类型。如果未提及或指定可见性模式,则默认情况下会考虑private模式。
- 当类的成员被声明为 public 时,就可以从任何地方访问它们。
- 当类中的成员被声明为protected时,它们就可以在基类和派生类中访问。
- 当类中的成员被声明为private时,它们只能被基类的成员和友元函数访问。
- 与public和protected访问说明符相比,private访问说明符为其数据成员提供更多的安全性。
- 将你的类属性声明为private(尽可能经常)被认为是一种很好的做法,因为这将有助于提高数据安全性。
- 访问修饰符主要用于数据隐藏和封装,因为它们可以帮助我们控制程序的哪一部分可以访问类的成员。这样就可以防止滥用数据。