C++是以C语言为基础,支持数据抽象和面向对象的程序设计语言。C++对C语言的扩充部分汲取了
许多著名语言中最优秀的特征,如从Algo168中吸取了操作符重载机制等。由于C++语言具有与C语言一
样的高执行效率,并容易被熟悉C语言的软件人员接受,因而很快得以流行。但这种混合型面向对象的
程序设计语言是一种新的程序设计语言,人们对它许多潜在的性能(封装、继承、多态等)还没有充分
地理解和应用,没有充分发挥其优势。多态性是面向对象系统的重要概念之一,它指的是同样的消息
能被发送到父类的对象和它的子类的对象。本文重点讨论多态性在程序设计中的应用。
1 多态性的实现形式
从广义上说,多态性是指一段程序能够处理多种类型对象的能力。在C++语言中,这种多态性可以
通过强制多态、重载多态、类型参数化多态、包含多态4种形式来实现。类型参数化多态和包含多态统
称为一般多态性,用来系统地刻画语义上相关的一组类型。重载多态和强制多态统称为特殊多态性,
用来刻画语义上无关联的类型间的关系。
包含多态是指通过子类型化,1个程序段既能处理类型T的对象,也能够处理类型T的子类型S的对
象,该程序段称为多态程序段。公有继承能够实现子类型。在包含多态中,1个对象可以被看作属于不
同的类,其间包含关系的存在意味着公共结构的存在。包含多态在不少语言中存在,如整数类型中的
子集构成1个子类型。每一个子类型中的对象可以被用在高一级的类型中,高一级类型中的所有操作可
用于下一级的对象。在C++中公有继承关系是一种包含多态,每一个类可以直接公有继承父类或多个父
类,如语句class D�public P1,public P2{……};表示类D分别是类P1和类P2的子类型。
类型参数化多态是指当1个函数(类)统一地对若干类型参数操作时,这些类型表现出某些公共的语
义特性,而该函数(类)就是用来描述该特性的。在类型参数化多态中,1个多态函数(类)必须至少带有
1个类型参数,该类型参数确定函数(类)在每次执行时操作数的类型。这种函数(类)也称类属函数(类)
。类型参数化多态的应用较广泛,被称为最纯的多态。
重载是指用同一个名字命名不同的函数或操作符。函数重载是C++对一般程序设计语言中操作符重
载机制的扩充,它可使具有相同或相近含义的函数用相同的名字,只要其参数的个数、次序或类型不
一样即可。例如:
int min(int x,int y); //求2个整数的最小数
int min(int x,int y,int z); //求3个整数的最小数
int min(int n,int a〔〕); //求n个整数的最小数
当用户要求增加比较2个字符串大小的功能时,只需增加:
char*min(char*,char*);
而原来如何使用这组函数的逻辑不需改变,min的功能扩充很容易,也就是说维护比较容易,同时也提
高了程序的可理解性,“min”表示求最小值的函数。
强制是指将一种类型的值转换成另一种类型的值进行的语义操作,从而防止类型错误。类型转换
可以是隐式的,在编译时完成,如语句D=I把整型变量转换为实型;也可以是显式的,可在动态运行
时完成。
从总体上来说,一般多态性是真正的多态性;特殊多态性只是表面的多态性。因为重载只允许某
一个符号有多种类型,而它所代表的值分别具有不同的、不相兼容的类型。类似地,隐式类型转换也
不是真正的多态,因为在操作开始前,各值必须转换为要求的类型,而输出类型也与输入类型无关。
相比之下,子类与继承却是真正的多态。类型参数化多态也是一种纯正的多态,同一对象或函数在不
同的类型上下文中统一地使用而不需采用隐式类型转换、运行时检测或其它各种限制。
2 多态性应用
2.1 包含多态
C++中采用虚拟函数实现包含多态,虚拟函数为C++提供了更为灵活的多态机制,这种多态性在程
序运行时才能确定,因此虚拟函数是多态性的精华,至少含有一个虚拟函数的类称为多态类。包含多
态在程序设计中使用十分频繁。
派生类继承基类的所有操作,或者说,基类的操作能被用于操作派生类的对象,当基类的操作不
能适应派生类时,派生类需重载基类的操作,见下例中的void circle::showarea()。
#include <iostream.h>
class point //屏幕上的点类
� {int x,y;
public;
point(int x1,int y1)
{x=x1;y=y1;}
void showarea()
{cout<<〃Area of point is:〃<<0.0<<endl;}
};
class circle:public point//圆类
{int radius;
public:
circle(int x,int y,int r):point(x,y){ radius=r;}
void showarea(){cout<<〃Area of circle is:〃<<3.14
*radius*radius<<endl;}
};
void disparea(const point*p) //多态程序段
{p->showarea();}
void main()
{circle c1(1,1,1);disparea(&c1);
}
程序的运行结果为0.0(正确结果应为3.14),出错的原因是:表达式p->showarea()中的函数调
用在编译时被束定到函数体上,使得这个表达式中的函数调用执行point类的showarea()。为此,当程
序员在实现一个派生类而变动了基类中的操作实现时,C++提供的虚函数机制可将这种变动告诉编译器
,即将关键字virtual放在类point中该函数的函数说明之前(virtual void showarea()),程序其它部
分保持不变(circle::showarea()自动地成为虚函数),编译器就不会对函数调用p->showarea()进
行静态束定(在编译/连接时进行的束定)而产生有关的代码,使函数调用与它所应执行的代码的束定
工作在程序运行时进行,这样上述程序的运行结果即为3.14。在程序运行时进行的束定被称为动态束
定。
利用虚函数,可在基类和派生类中使用相同的函数名定义函数的不同实现,从而实现“一个接口
,多种方式”。当用基类指针或引用对虚函数进行访问时,软件系统将根据运行时指针或引用所指向
或引用的实际对象来确定调用对象所在类的虚函数版本。
C++语言还增加了纯的虚函数机制用来更好地设计包含多态性。对于如图1(a)所示结构的类层次,
假如每个类中都有一个函数“void display(void);”,那么,怎样对它们按多态性进行统一处理呢
?对这类问题应先设计一个抽象的类,使它成为所有类的祖先类,如图1(b)所示。设置类A的目的是由
它说明统一使用该层次中的display()函数的方法(赋值兼容规则从语法上保证了A的子孙类可按A说明
的方式使用display()函数;多态性则从语义上保证了在执行时,根据实际的对象访问相应对象类中的
display()函数)。
为了保证在类A中设置的display()函数是抽象动作,并能说明类A是一个抽象的类,在C++中,可用纯
的虚函数语言机制在类A中声明1个成员函数“virtual void display(void)=0;”。请注意,在类A
的子孙类中要么给出display()的定义,要么重新将该函数声明为纯的。
从上面的分析可以看出,类A的设计尽管是用继承性语法表达的,但它的主要目的不是为代码共享而设
计的,而是为了提高多态性而设计的,它是另一个维度的抽象。
2.2 类型参数化多态
参数化多态又称非受限类属多态,即将类型作为函数或类的参数,避免了为各种不同的数据类型
编写不同的函数或类,减轻了设计者负担,提高了程序设计的灵活性。
模板是C++实现参数化多态性的工具,分为函数模板和类模板二种。
类模板中的成员函数均为函数模板,因此函数模板是为类模板服务的。类模板在表示数组、表、
矩阵等类数据结构时,显得特别重要,因为这些数据结构的表示和算法的选择不受其所包含的元素的
类型的影响。下面是一个通用数组类模板的定义。
template <class T,int N>
class array
{T elem〔N〕;
public:
array(){for(int j=0;j<N;j++)elem〔j〕=0;}
T& operator〔〕(int index){return elem〔index〕;}
void modi(int index,T value){elem〔index〕=value;}
};
其中,T是类型参数,N是常量参数。T和N的实际值是在生成具体类实例时指定的。类模板的< >
可以包括任意个类型参数或常量参数,但至少应有一个参数。在类模板定义中,可在程序中通常使用
类型指定的任何地方使用类型参数,可在通常使用特定类型常量表达式的任何地方使用常量参数。
成员函数模板可放在类模板中定义,也可放在类外定义,例如:
template <class T,int N>
T& array<T,N>::operator〔〕(int index){return elem〔index〕;}
当由类模板生成一个特定的类时,必须指定参数所代表的类型(值)。例如,1个元素类型为int、
长度为100的数组类使用类型表达式array<int,100>来表示,这个类型表达式被用于说明数组类对
象。例如:
array<int,100> a: //生成特定类的对象a
a.modi(1,34); //对象a访问成员函数
类模板一旦生成了对象和指定了参数表中的类型,编译器在以后访问数据成员和调用成员函数时
完全强制为这些类型。
在C++中可以重载定义多个同名的函数模板,也可以将1个函数模板与1个同名函数进行重载定义。
例如:
template <class T> T min(T a,T b){return a<b?a:b;}
template <class T>
T min(T a,T b,T c){T x=min(a,b);return min(x,c);}
int min(int a,int b)〔return a<b?a:b;}
调用min(3,7),则调用第3个函数;调用min(3.8.5.9),编译器将根据带2个参数的模板生成新函
数min(double,double);调用min(4,90,76),则编译器根据带3个参数的模板生成新函数min(int,
int,int);而调用min(56.3,48,71),编译将给出错误信息,说明无法从上面的模板中生成函数
min(double,double,double),因为编译器在类型推导时,不存在类型强制。
模板描述了1组函数或1组类,它主要用于避免程序员进行重复的编码工作,大大简化、方便了面
向对象的程序设计。
2.3 重载多态
重载是多态性的最简形式,而且把更大的灵活性和扩展性添加到程序设计语言中,它分成操作符
重载和函数重载。
C++允许为类重定义已有操作符的语义,使系统预定义的操作符可操作类对象。C++语言的一个非
常有说服力的例子是count对象的插入操作(<<)。由于其类中定义了对位左移操作符“<<”进行重
载的函数,使C++的输出可按同一种方式进行,学习起来非常容易。并且,增加一个使其能输出复数类
的功能(扩充)也很简单,不必破坏原输出逻辑。
C++规定将操作符重载为函数的形式,既可以重载为类的成员函数,也可以重载为类的友员函数。
用友员重载操作符的函数也称操作符函数,它与用成员函数重载操作符的函数不同,后者本身是类中
成员函数,而它是类的友员函数,是独立于类的一般函数。注意重载操作符时,不能改变它们的优先
级,不能改变这些操作符所需操作数的个数。
重定义已有的函数称为函数重载。在C++中既允许重载一般函数,也允许重载类的成员函数。如对
构造函数进行重载定义,可使程序有几种不同的途径对类对象进行初始化。还允许派生类的成员函数
重载基类的成员函数,虚函数就属于这种形式的重载,但它是一种动态的重载方式,即所谓的“动态
联编(束定)”。
2.4 强制多态
强制也称类型转换。C++语言定义了基本数据类型之间的转换规则,即:
char->short->int->unsigned->long->unsigned long->float->double->long
double
赋值操作是个特例,上述原则不再适用。当赋值操作符的右操作数的类型与左操作数的类型不同
时,右操作数的值被转换为左操作数的类型的值,然后将转换后的值赋值给左操作数。
程序员可以在表达式中使用3种强制类型转换表达式:①static_cast<T>(E);②T(E);③(T)E
。其中任意一种都可改变编译器所使用的规则,以便按自己的意愿进行所需的类型强制。其中E 代表
一个运算表达式,T代表一个类型表达式。第三种表达形式是C语言中所使用的风格,在C++中,建议不
要再使用这种形式,应选择使用第一种形式。例如,设对象f的类型为double,且其值为3.14。则表达
式static_cast<int>(f)的值为3,类型为int。
通过构造函数进行类类型与其它数据类型之间的转换必须有一个前提,那就是此类一定要有一个
只带1个非缺省参数的构造函数,通过构造函数进行类类型的转换只能从参数类型向类类型转换,而想
将一个类类型向其它类型转换是办不到的。类类型转换函数就是专门用来将类类型向其它本类型转换
的,它是一种类似显式类型转换的机制。转换函数的设计有以下几点要特别注意:①转换函数必须是
类的成员函数;②转换函数不可以指定其返回值类型;③转换函数其参数行不可以有任何参数。
强制使类型检查复杂化,尤其在允许重载的情况下,导致无法消解的二义性,在程序设计时要注
意避免由于强制带来的二义性。
C++特点:
C++定义类最大的特点是使程序面向对象而不是面向过程,这在c中是没有体现的。 类的标志特性是继承,封装,多态,对象化提供了模型化和信息隐藏的好处,类化提供了可重用性的好处。通过面向对象使得程序设计模块化了,便于编程人员拆分合作。类首先是基类,派生和继承得到新的类即有基类的公共属性,又可以定义新的功能属性,便有了多元化实用价值。封装便于保护代码不被任意篡改和便于维护,可移植性和重用性高。多态说的是程序因而变得更加灵活,多态性允许将父对象设置成为和一个或多个它的子对象相等的技术,比如Parent:=Child; 多态性使得能够利用同一类(基类)类型的指针来引用不同类的对象,以及根据所引用对象的不同,以不同的方式执行相同的操作。
C++对C语言有哪些发展。基本上没有啥影响,它们是思想方向不同的编程语言,互为补充。
C语言是结构化和模块化的面向过程的语言,C++语言是面向对象的程序设计语言。C++语言是C语言的超集,也就是说学会了C++,你其实已经把C语言学会了。至于说有什么区别,应该说是编程思想的区别吧,C是基于过程的,强调的是程序的功能,以函数(功能)为中心。C++是面向对象的,强调程序的分层、分类,以抽象为基础,进行对象的定义与展示,即程序设计。具体说来话长。建议你学习C++的时候,学会用面向对象的方式思考和编程。现在在开发大项目的时候,都是应用面向对象的分析和设计的技术。
表示作用域,和所属关系。 ::是运算符中等级最高的,它分为三种:1)global scope(全局作用域符),用法(::name)2)class scope(类作用域符),用法(class::name)3)namespace scope(命名空间作用域符),用法(namespace::name)他们都是左关联(left-associativity)他们的作用都是为了更明确的调用你想要的变量,如在程序中的某一处你想调用全局变量a,那么就写成::a,如果想调用class A中的成员变量a,那么就写成A::a,另外一个如果想调用namespace std中的cout成员,你就写成std::cout。扩展资料:C++语言特点:
支持数据封装和数据隐藏在C++中,类是支持数据封装的工具,对象则是数据封装的实现。C++通过建立用户定义类支持数据封装和数据隐藏。在面向对象的程序设计中,将数据和对该数据进行合法操作的函数封装在一起作为一个类的定义。对象被说明为具有一个给定类的变量。每个给定类的对象包含这个类所规定的若干私有成员、公有成员及保护成员。完好定义的类一旦建立,就可看成完全封装的实体,可以作为一个整体单元使用。类的实际内部工作隐藏起来,使用完好定义的类的用户不需要知道类是如何工作的,只要知道如何使用它即可。支持继承和重用在C++现有类的基础上可以声明新类型,这就是继承和重用的思想。通过继承和重用可以更有效地组织程序结构,明确类间关系,并且充分利用已有的类来完成更复杂、深入的开发。新定义的类为子类,成为派生类。它可以从父类那里继承所有非私有的属性和方法,作为自己的成员。支持多态性采用多态性为每个类指定表现行为。多态性形成由父类和它们的子类组成的一个树型结构。在这个树中的每个子类可以接收一个或多个具有相同名字的消息。当一个消息被这个树中一个类的一个对象接收时,这个对象动态地决定给予子类对象的消息的某种用法。多态性的这一特性允许使用高级抽象。继承性和多态性的组合,可以轻易地生成一系列虽然类似但独一无二的对象。由于继承性,这些对象共享许多相似的特征。由于多态性,一个对象可有独特的表现方式,而另一个对象有另一种表现方式。参考资料:百度百科-C++
c++是一门复合语言,即面向对象也面向过程,并且c++支持指针,而java的指针是不被程序员所使用的,
多态就相当于一个switch结构,那些具体的理论的话建议写个程序自己体会,实践才是硬道理嘛
C++语言是对C语言的扩展,是C语言的超集。C语言是 美国贝尔实验室 在1969~1973年开发的,与此同时,还用它开发了UNIX操作系统。C语言又是由B语言衍生而来的,B语言是贝尔实验室的 Ken Thompson 在BCPL语言的基础上开发的,并用它编写了第一个UNIX操作系统。BCPL语言是 英国剑桥大学 的 Martin Richards ,60年代在美国MIT时设计的。
1971年,贝尔实验室的 Dennis Ritchie 扩展了B语言(通过增加类型),他称之为NB,即New B。在更改了B语言的结构,并重写了B语言的编译器后,Ritchie称他的新语言为C。1983年,出现了许多C语言的版本, 美国国家标准化协会(ANSI) 在1989年出版了标准的C语言,称之为ANSI C。
也是在1983年,贝尔实验室的 Bjarne Stroustrup 在C语言的基础上,创建了C++语言,它是为UNIX系统环境设计的。C++语言增强了C语言的能力,使得程序员能够改进编写程序的质量,并易于程序代码的复用。C++语言的ISO标准已在1997年11月被一致通过,1998年8月被正式批准。
C++语言在1980年开始被使用,"C++"这个名字是由Rick Maseitti提出,到1983年夏确定的。C++的创作灵感来源于当时计算机语言多方面的成果,特别是BCPL语言(Basic Combined Programming Language, 它也是C语言的来源之一)和Simula 67语言(以面向对象为核心的语言),同时还借鉴了Algol 68。就如同它的名字表达的那样,C++语言是C语言的一个超集,它是一门混合型的语言,既支持传统的结构化程序设计,又支持面向对象的程序设计,这是C++语言成功流行的一个重要原因。
读者可能产生疑问,既然面向对象的程序设计方法比结构化的程序设计方法先进许多,为什么C++语言仍旧支持后者,而不愿意成为一门纯粹的面向对象的程序设计语言?
实际上,这种做法也是从程序设计语言发展实践中得到的经验。面向对象程序设计的概念提出后,某些公司和机构曾经开发出一些纯面向对象的语言,比如第一个成功的、纯面向对象的程序设计语言的Smalltalk,但是由于广大的程序员不能一下子完全接受面向对象程序设计的思想,不能完全适应面向对象程序设计的技术,这些语言都没有能够广泛的流行起来。事实上,程序员们长期采用结构化的程序设计方法,并从中汲取了许多宝贵经验,形成了巨大的财富,这些财富应该得到继承和发展;而且结构化程序设计方法在小型软件项目的开发设计上仍然很适用,完全否定这种设计方法也是不恰当的。C++作为一门混合型语言,在增加对于面向对象方法的支持的同时,还继承了传统程序设计语言C的优点,克服了其不足之处,使得自身既适用于结构化程序设计,又能满足面向对象程序设计的要求,这就符合广大程序员逐步更新其程序设计观念和方法的要求,因而很快流行起来。总之,对于传统的财富不是完全抛弃,而是继承并发展之,是C++语言成功的重要原因。
C++从C语言发展而来,比C更好, 其优点主要包括:
(1) 与C语言兼容,既支持面向对象的程序设计,也支持结构化的程序设计。同时,熟悉C语言的程序员,能够迅速掌握C++语言。
(2) 修补了C语言中的一些漏洞,提供更好的类型检查和编译时的分析。使得程序员在C++环境下继续写C代码,也能得到直接的好处。
(3) 生成目标程序质量高,程序执行效率高。一般来说,用面向对象的C++编写的程序执行速度与C语言程序不相上下。
(4) 提供了异常处理机制,简化了程序的出错处理。利用throw、try和catch关键字,出错处理程序不必与正常的代码紧密结合,提高了程序的可靠性和可读性。
(5) 函数可以重载及可以使用缺省参数。重载允许相同的函数名具有不同参数表,系统根据参数的个数和类型匹配相应的函数。缺省参数可以使得程序员能够以不同的方法调用同一个函数,并自动对某些缺省参数提供缺省值。
(6) 提供了模板机制。摸板包括类摸板和函数模板两种,它们将数据类型作为参数。对于具体数据类型,编译器自动生成模板类或模板函数,它提供了源代码复用的一种手段。
C++语言对C语言扩充和增强的几点具体体现
C++在增加面向对象的特征之外,还对C语言进行了扩充和增强。主要的增强点有如下几个:
1. 注释
在C语言块注释的形式
/*
Explanation Sentence
*/
的基础上,C++语言提供了一种新的单行注释形式:
//Explanation Sentence
即用"//"表示注释开始,从该位置直到当前行结束的所有字符都被作为注释。
举个简单的例子:
例1-4:
/*
下面的程序段计算从1到100的整数和,
结果记录在变量sum中
*/
sum = 0; //变量sum初值置为零
for(i = 1; i <= 100; i++)
{//循环体开始
sum += i; // 依次累加i
}
2. 更加灵活的变量说明
在传统的C语言中,局部变量的说明必须集中放在执行代码的前面,数据说明语句和执行语句的混合将引起编译错误。而在C++中,可以在程序代码块的任何地方进行局部变量的说明。比如下面的代码在C语言中是不正确的,在C++语言中却可以正常运行。
for(int i = 1; i < = 100; i++);
这样做的好处是使变量的定义和它的使用集中在一起,意义一目了然。
3. 更加严格的函数原型说明
C++摒弃了C语言对函数原型随意简化的方式,这种简化是许多C语言程序错误的根源。C++语言要求编程者为函数提供完整的原型,包括全部参数的类型和返回值得说明。
例如,有字符型和双精度类型两个参数、返回整型值的函数f,原型应该写为:
int f(char, double);
而C语言中允许将这个原型写成"f( );"。
在函数原型说明中,参数名可有可无,并且可以和函数定义中的参数名不一致。
4. 增加了函数重载机制
重载是程序语言领域的重要概念。常规语言中最典型的例子是"+、-、×、/"等各种算术运算符的重载,这些符号可以同时用来表示多种类型数据之间的运算,这种对一个名字或一个符号赋予多重意义的情况就叫重载。
C++语言增加了C语言所没有的函数重载机制。对一个函数名可以给出多个函数定义,只要这些定义可以通过参数个数或类型的不同区别开来即可。
C++还允许对系统中预先定义的运算符号进行重载,增加新的定义。这样做的优点是在今后对新定义类型的变量进行运算时,计算公式写起来方便自然。
5. 函数缺省参数
C++中允许函数有缺省参数。所谓缺省,是指函数调用时可以不给出实际的参数值。下面是一个有缺省参数的函数定义的实例:
例1-5:
int f(int a, int b=1)
{
return a*b;
}
此后,函数调用f(3,1)和f(3)将返回同样的结果。
6. 更加方便的动态存储分配
C++为了提高内存管理上的灵活性,提供了动态内存分配合释放的操作符new和delete,用来增强C语言中原有的函数malloc()和free();
7. 增加了内联函数(Inline Function)
C++提供了内联函数,用以代替C语言中的宏。宏的处理机构是预处理器而不是编译器,它虽然可以提高效率,但是却不能实现函数调用所拥有的参数类型检查等机制。内联函数不但能够象宏那样节约函数调用时保存现场所需的系统开销,提高程序执行效率,还保留了函数进行参数类型检查的机制;并且C++语言中的宏是不能够存取对象私有成员变量的,但是使用内联函数,则没有这一限制。
8. 输入/输出流机制
C++保留了C语言标准库中各种输入/输出函数,而且提供了一套新的输入/输出机制――流机制。
比如向标准输出输出一个字符串:
cout<<"C++ is beautiful!";
或者由标准输入读一个整数,赋给变量a
int a;
cin>>a;
流式输入/输出运算符能够根据变量类型自动确定数据交换过程中的转换方式,还可以定义"<<、>>"的重载,方便了编程者自定义类型的数据的输入/输出。
9. 作用域限定运算符::
作用域限定运算符::用于对当前作用域之外的同名变量进行访问。例如在下面的例子中,我们可以利用::实现在局部变量a的作用域范围内对全局变量a的访问。