1、第12章 C+语言编程基础,C+程序设计语言可以看作C语言的改进和升级,不仅完全兼容了C语言的语法和函数库,还引入了面向对象、运算符重载、多态性、数据流和模板等最新的编程思想。极大地保证了源代码的生产率、质量和可重用性。GNU项目为Linux系统上C+开发提供了G+编译器,GDB调试器也能用来调式C+程序。本章简单讲解C+语言的特性与基本用法。,12.1 类和数据抽象,类和数据抽象是面向对象思想的基本范畴,面向对象思想将任何事物看作对象,对象有自己的属性和行为,收集这些属性就是数据抽象的任务。如果把同一类事物的属性和行为作为一个类别来认识,这个类别就是该类事物的类,每一个有相同属性和行为的事物
2、都是该类的对象。,12.1.1 用类实现数据抽象,在C+语言中,类是封装的程序包。程序包里有自身的数据和函数,这些数据可看作属性,函数可看作是行为。对象是由类在源代码中生成出来独立的程序体,对象具有类的全部属性和行为。因此可以认为,对象是有“生命”的程序体,它能通过行为改变自己的属性,也能根据属性产生不同的行为。,12.1.2 类作用域和访问类成员,类的作用域是整个文件,类的成员数据和成员函数的作用域在该类之中。类的所有成员函数在类的内部都可以直接访问其他类成员,并且可以按名称引用。在成员函数中定义的变量,作用域是该函数。如果成员函数定义了与类成员具有相同名称的数据,要访问同名的类成员需要加入
3、作用域解析运算符(:)。,12.1.3 从实现中分离接口,良好的软件工程习惯要求接口与实现分离。这种方式使程序的修改更为容易,正如使用类的程序所关心,只要类的接口没有变化,对类内部的改变不会影响程序的其他部分。 类的接口应在设计时尽量考虑周全,避免过于频繁的改动。当程序需要使用该类时,只用在程序文件中包含类的接口文件。,12.1.4 控制访问成员,成员的默认访问模式是private,因此类定义的开始到第一个成员访问说明符之间的所有成员都是private成员。在每个成员访问说明符之后,由该成员说明符所调用的模式将在下一个成员访问说明符或者类定义结束之前保持有效。成员访问说明符可以重复,但通常我们
4、将同一类成员方在一起说明,这样可避免混淆。,12.1.5 构造函数和析构函数,所有的类都可定义一个或多个构造函数和析构函数。构造函数是与类同名的函数,构造函数的作用是在对象生成时初始化成员数据。C+语言规定,每个类必须有构造函数,如果没有为该类定义构造函数,那么编译器会自动加上一个没有参数的默认构造函数,默认构造函数不会对类成员数据进行初始化。,12.1.6 const对象和const成员函数,const修饰符的作用是声明常量型的变量,修改const类型的数据将引起编译错误。对象也可以被定义为const类型,这样该对象内的数据就不能再修改。如下例所示:const Buddy b(“Tom“,
5、1234567890, “China“); / 生成常量对象b.setBuddy(“Jerry“, 4567890123, “USA“); / 该语句是非法的 当对象b被定义为const类型后,任何途径对成员数据的修改都是错误的。C+语言还规定,只有被定义为const类型的成员函数才能访问const类型对象的数据。即使成员函数Buddy:printBuddy()不会修改该对象的数据,也被拒绝访问。所以,当对象被当作const类型使用时,需要用到的成员函数必须定义为const类型。,12.1.7 friend对象和friend类,friend被称作友元。类的friend函数并不是该类的成员函数,
6、但被定义为该类的友元后,friend函数可以访问类的private成员。 friend函数引用的参数是类的地址,通过类的地址就可以访问该类的成员。这一用法与指针的原理是相似的。 类也可以作为另一个类的友元,例如Class2类作为Class1类的友元,那么需要在Class1类的定义中将Class2类定义为友元。,12.1.8 this指针,this指针是类定义中指向自身的指针,每个对象都可以通过this指针来访问它自己的地址。对象的this指针并不是对象本身的组成部分,它不占用对象的内存空间。在每次非static成员函数调用对象的时候,this指针作为隐藏的第一个参数由编译器传递给对象。,12.
7、1.9 动态内存分配,在C语言中,动态分配内存可使用malloc()和free()函数,这种分配方式必须指定分配内存空间的长度。C+语言提供了new和delete运算符执行动态内存分配,这种分配方式优于C语言的分配方式,申请内存一般形式是: 指针名 = new 数据类型; 释放内存的形式为: delete指针名;,12.1.10 static类成员,在C语言中static修饰符用来定义静态数据类型,如果将类成员数据定义为static类型,那么该类生成的所有对象将使用同一个内存空间保存该成员数据。,12.2 C+特性,上一节简单介绍了C+语言的类和数据抽象,这只是C+语言作为面向对象语言的基本特
8、性。除此以外,运算符重载、继承、虚拟函数和多态性、流输入与输出、模板、异常处理都是C+语言的重要特性。本节将讲解对这些特性的概要。,12.2.1 运算符重载,在C+语言的定义中,很多运算符只能对简单的数据结构进行操作。 程序的开始为字符串设计了类,重载的运算符被定义为该类的一个成员函数,字符串相加在重载运算符函数中实现。主函数中执行的操作“s1 + s2”实际上等同于s1.operator+(s2),重载运算符的作用是简化了此函数的表达方式。,12.2.2 继承,面向对象编程的一个重要特性是继承,继承是指利用一个类生成另一个类的对象,前者称为父类,后者称为子类。子类不但获得了父类的所有成员,还
9、可以加上它自己的一些成员。,12.2.3 虚拟函数和多态性,虚拟函数是一种特殊的成员,该成员在父类中定义但不实现该函数的细节,而将细节留在子类中进行实现。虚拟函数必须加上关键字virtual,以便可以使用指针对指向相应的对象进行操作。多态性是通过虚拟函数实现的,即通过同一父类的虚拟函数,子类实现不如的细节。,12.2.4 流输入与输出,C+输入与输出操作是通过控制数据流实现的,流是数据的字节序列。输入操作中,数据从输入设备流向内存;输出操作中,数据从内存流向输出设备。C+提供了流输入输出函数库,函数库的名称是“iostream”。该函数库将流输入输出定义为操作符“”和“”和“”是通过在这3个函
10、数中的重载而实现的。cin函数的作用是输入数据流,cout的作用是输出数据流,endl函数的作用是立即将缓存中的数据全部输出。,12.2.5 模板,模板是C+中更高级的特性,利用模板,不仅可以指定全部相关的函数重载,即模板函数,还可以指定全部相关的类,即模板类。模板可以生成通用的函数,这些函数不仅能够接受任意数据类型的实际参数,而且可返回任意类型的值。使用模板后,不需要对所有可能的数据类型进行函数重载,简化了成员函数设计的难度。,12.2.6 异常处理,在程序运行中,很多时候无法确定一段代码是否是能够正常工作,程序出错的原因可能是因为程序访问了并不存在的资源,或者由于一些变量超出了预期的范围,等等。这些情况我们统称为异常,C+新近引入的三种操作符能够帮助我们处理这些出错情况:try、throw和catch。,12.3 小结,本章介绍了C+语言的面向对象程序设计思想和一些新的特性,C+语言并不是本书的重点,所以因篇幅有限,不能涵盖这些内容的全部知识点。在Linux系统程序设计中,特别GTK+是图形化程序设计,使用了大量与面向对象编程有关的思想,学习C+语言对理解这些新的编程思想有极大的帮助。C语言编程在面向对象语言盛行的时代,仍然能保持其生命活力,其主要原因就是C语言的简洁更适合一些系统编程,如嵌入式Linux系统上的程序设计。Linux系统上,提供给C语言的开源代码资源也更多。,