当前位置: 首页 > 编程笔记 >

深入解析C++编程中类的封装特性

邹麻雀
2023-03-14
本文向大家介绍深入解析C++编程中类的封装特性,包括了深入解析C++编程中类的封装特性的使用技巧和注意事项,需要的朋友参考一下

共用接口和私有实现的分离

C++通过类来实现封装性,把数据和与这些数据有关的操作封装在一个类中,或者说,类的作用是把数据和算法封装在用户声明的抽象数据类型中。

实际上用户往往并不关心类的内部是如何实现的,而只需知道调用哪个函数会得到什么结果,能实现什么功能即可。

在声明了一个类以后,用户主要是通过调用公用的成员函数来实现类提供的功能(例如对数据成员设置值,显示数据成员的值,对数据进行加工等)。因此,公用成员函数是用户使用类的公用接口(public interface),或者说是类的对外接口。

类中被操作的数据是私有的,实现的细节对用户是隐蔽的,这种实现称为私有实现(private implementation)。这种“类的公用接口与私有实现的分离”形成了信息隐蔽。

软件工程的一个最基本的原则就是将接口与实现分离,信息隐蔽是软件工程中一个非常重要的概念。它的好处在于:
如果想修改或扩充类的功能,只需修改本类中有关的数据成员和与它有关的成员函数,程序中类外的部分可以不必修改。
如果在编译时发现类中的数据读写有错,不必检查整个程序,只需检查本类中访问这些数据的少数成员函数。
类声明和成员函数的分离

面向对象的程序开发中,一般做法是将类的声明(其中包含成员函数的声明)放在指定的头文件中,用户如果想用该类,只要把有关的头文件包含进来即可。

由于在头文件中包含了类的声明,因此在程序中就可以用该类来定义对象。由于在类体中包含了对成员函数的声明,在程序中就可以调用这些对象的公用成员函数。

为了实现上一节所叙述的信息隐蔽,对类成员函数的定义一般不放在头文件中,而另外放在一个文件中。

例如,可以分别写两个文件:
student.h头文件

//这是student.h头文件,在此文件中进行类的声明
class Student //类声明
{
  public :
  void display( );//公用成员函数原型声明
  private :
  int num;
  char name[20];
  char sex;
};

student.cpp

// 在此文件中进行函数的定义
#include <iostream>
#include "student.h"//不要漏写此行,否则编译通不过
void Student::display()//在类外定义display类函数
{
  cout<<"num:"<<num<<endl;
  cout<<"name:"<<name<<endl;
  cout<<"sex:"<<sex<<endl;
}

为了组成一个完整的源程序,还应当有包括主函数的源文件(main.cpp):

// 主函数模块
#include <iostream>
#include ″student.h″ //将类声明头文件包含进来
int main( )
{
  Student stud; //定义对象
  stud.display( ); //执行stud对象的display函数
  return 0;
}

这是一个包括3个文件的程序,组成两个文件模块:一个是主模块main.cpp,一个是student.cpp。在主模块中又包含头文件student.h。在预编译时会将头文件student.h中的内容取代#include ″student.h″行。

请注意,由于将头文件student.h放在用户当前目录中,因此在文件名两侧用双撇号包起来(″student.h″)而不用尖括号(<student.h>),否则编译时会找不到此文件。

使用C++编译系统对两个源文件main.cpp和student.cpp分别进行编译,得到两个目标程序main.obj和student.obj,然后将它们和其他系统资海连接起来,形成可执行文件main.exe,见图 。

注意,目标文件的后缀在不同的C++编译系统中是不同的,例如在GCC中,后缀是 .o,这里使用 .obj 是对VC 6.0而言。

在运行程序时调用stud中的display函数,输出各数据成员的值。

有的读者可能会考虑这样一个问题:如果一个类声明多次被不同的程序所调用,每次都要对包含成员函数定义的源文件(如上面的student.cpp进行编译,这是否可以改进呢?的确,可以不必每次都对它重复进行编译,而只需编译一次即可。把第一次编译后所形成的目标文件保存起来,以后在需要时把它调出来直接与程序的目标文件相连接即可。 这和使用函数库中的函数是类似的。

这也是把成员函数的定义不放在头文件中的一个好处。如果对成员函数的定义也放在类声明的头文件中,那么在对使用这些类的每一个程序的每一次编译时都必然包括对成员函数定义的编译,即同一个成员函数的定义会多次被重复编译。只有把对成员函数的定义单独放在另一文件中,才能做到单独编译。

在实际工作中,并不是将一个类声明做成一个头文件,而是将若干个常用的功能相近的类声明集中在一起,形成类库。

类库有两种:一种是C++编译系统提供的标准类库;—种是用户根据自已的需要做成的用户类库,提供给自己和自己授权的人使用,这称为自 定义类库。在程序开发工作中,类库是很有用的,它可以减少用户自己对类和成员函数进行定义的工作量。

类库包括两个组成部分:类声明头文件;已经过编译的成员函数的定义,它是目标文件。

用户只需把类库装入到自己的计算机系统中(一般装到C++编译系统所在的子目录下),并在程序中用#include命令行将有关的类声明的头文件包含到程序中,就可以使用这些类和其中的成员函数,顺利地运行程序。这和在程序中使用C++系统提供的标准函数的方法是一样的,例如用户在调用sin函数时只需将包含声明此函数的头文件包含到程序中,即可调用该库函数,而不必了解sin函数是怎么实现的(函数值是怎样计算出来的)。

当然,前提是系统已装了标准函数库。在用户源文件经过编译后,与系统库(是目标文件)相连接。

在用户程序中包含类声明头文件,类声明头文件就成为用户使用类的公用接口,在头文件的类体中还提供了成员函数的函数原型声明,用户只有通过头文件才能使用有关的类。用户看得见和接触到的是这个头文件,任何要使用这个类的用户只需包含这个头文件即可。包含成员函数定义的文件就是类的实现。

请特别注意,类声明和函数定义一般是分别放在两个文本中的。由于要求接口与实现分离,为软件开发商向用户提供类库创造了很好的条件。

开发商把用户所需的各种类的声明按类放在不同的头文件中,同时对包含成员函数定义的源文件进行编译,得到成员函数定义的目标代码。软件商向用户提供这些头文件和类的实现的目标代码(不提供函数定义的源代码)。用户在使用类库中的类时,只需将有关头文件包含到自己的程序中,并且在编译后连接成员函数定义的目标代码即可。

由于类库的出现,用户可以像使用零件一样方便地使用在实践中积累的通用的或专用的类,这就大大减少了程序设计的工作量,有效地提高了工作效率。

 类似资料:
  • 本文向大家介绍深入解析C++编程中线程池的使用,包括了深入解析C++编程中线程池的使用的使用技巧和注意事项,需要的朋友参考一下 为什么需要线程池 目前的大多数网络服务器,包括Web服务器、Email服务器以及数据库服务器等都具有一个共同点,就是单位时间内必须处理数目巨大的连接请求,但处理时间却相对较短。 传 统多线程方案中我们采用的服务器模型则是一旦接受到请求之后,即创建一个新的线程,由该线程执行

  • 本文向大家介绍理解C++编程中的std::function函数封装,包括了理解C++编程中的std::function函数封装的使用技巧和注意事项,需要的朋友参考一下 先来看看下面这两行代码: 这两行代码是从Cocos2d-x中摘出来的,重点是这两行代码的定义啊。std::function这是什么东西?如果你对上述两行代码表示毫无压力,那就不妨再看看本文,就当温故而知新吧。 std::functi

  • 本文向大家介绍深入解析Java编程中接口的运用,包括了深入解析Java编程中接口的运用的使用技巧和注意事项,需要的朋友参考一下 接口的本质——接口是一种特殊的抽象类,这种抽象类里面只包含常量和方法的定义,而没有变量和方法的实现。   抽象类所具有的一些东西接口可以具有,假如一个抽象类里面所有的方法全都是抽象的,没有任何一个方法需要这个抽象类去实现,并且这个抽象类里面所有的变量都是静态(static

  • 本文向大家介绍C++封装远程注入类CreateRemoteThreadEx实例,包括了C++封装远程注入类CreateRemoteThreadEx实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C++封装远程注入类CreateRemoteThreadEx的方法,分享给大家供大家参考。具体方法如下: 首先,类初始化时传入要注入的DLL文件名 只使用两个函数 .h头文件如下: .cpp源文

  • 本文向大家介绍深入理解C♯ 7.0中的Tuple特性,包括了深入理解C♯ 7.0中的Tuple特性的使用技巧和注意事项,需要的朋友参考一下 介绍 Tuple是异类对象的有序序列。 我们经常可以写出返回多个值的方法,所以我们需要创建一个包含多个数据元素的简单结构。 为了支持这些情况,Tuple 被添加到 C#。 Tuple 是包含多个字段用来表示数据成员的轻量级数据结构。 如果一个方法返回多个相同类

  • 本文向大家介绍深入解析Swift编程中枚举类型的相关使用,包括了深入解析Swift编程中枚举类型的相关使用的使用技巧和注意事项,需要的朋友参考一下 枚举是由用户定义的数据类型的一组相关值。关键字 enum 用来定义枚举数据类型。 枚举功能 枚举在 swift 也类似于 C 和 Objective C 中结构类型 它是在一个类中声明,其值是通过该类的实例来访问 初始成员值是用枚举初始化定义的 其功能