c++12
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2
C++语言程序设计
多态性的概念
多态性是面向对象程序设计的重要特征之一。 多态性是指发出同样的消息被不同类型的对象 接收时有可能导致完全不同的行为。 多态性是面向对象编程最重要的特征之一,是 指不同的对象对同一命令做出不同响应的能力。 如简单的例子:P12A.cpp、P12B.cpp 多态的实现:
例2:
C++语言程序设计
void main() #include<iostream.h> { cout<<“first:\n”; class Base Base *bc=new Base; {public: Base(){cout<<“construct in Base\n”;} cout<<“second\n”; ~Base() Subclass *sc=new {cout<<“destruting Base”<<endl;} Subclass; }; cout<<“calling class Subclass:public Base test(bc)\n”; {public: test(bc); Subclass() {cout<<“construct in Subclass\n”;} cout<<“calling ~Subclass() test(sc)\n”; {cout<<“destruting test(sc); Subclass”<<endl;} cout<<“end!\n”; }; void test(Base *x) } { delete x; } 25
运行结果: B1::display() D1::display()
18
C++语言程序设计
总结:
一个函数一旦被说明为虚函数,则无 论说明它的类被继承了多少层,在每 一层派生类中该函数都保持virtual特 性。因此,在派生类中重新定义该函 数时,不再需要关键字virtual。 但习惯上,为了提高程序的可读性, 常常在每层派生类中都重复地使用 virtual关键字。
9
C++语言程序设计
例
虚 函 数
#include <iostream> using namespace std; class B0 //基类B0声明 {public: //外部接口 virtual void display() //虚成员函数 {cout<<"B0::display()"<<endl;} }; class B1: public B0 //公有派生 { public: void display() { cout<<"B1::display()"<<endl; } }; class D1: public B1 //公有派生 { public: void display() { cout<<"D1::display()"<<endl; } };
例1:
C++语言程序设计
void main() { cout<<“first:\n”; Base *bc=new Base; cout<<“second\n”; *sc=new #include<iostream.h> Subclass; class Base cout<<“end!\n”; {public: Base(){cout<<“construct in Base\n”;} } ~Base() 输出: {cout<<“destruting Base”<<endl;} first: }; construct in Base class Subclass:public Base second {public: Subclass() construct in Base {cout<<“construct in Subclass\n”;} construct in Subclass ~Subclass() end! {cout<<“destruting Subclass”<<endl;} }; 24
14
C++语言程序设计
纯虚函数与抽象类
纯 虚 纯虚函数的声明格式为: virtual 类型 函数名(参数表)=0; 函 即没有函数体的函数。 数 带有纯虚函数的类称为抽象类: 与 class 类名 抽 { 象 virtual 类型 函数名(参数表)=0; //纯虚函数 类
...
}
15
C++语言程序设计
22
C++语言程序设计
void main() { cout<<“first:\n”; Base bc; cout<<“second:\n”; Subclass sc; class Base cout<<“end!\n”; {public: Base(){cout<<“construct in Base\n”;} } 输出: ~Base() {cout<<“destruting Base”<<endl;} first: }; construct in Base class Subclass:public Base second: {public: construct in Base Subclass() {cout<<“construct in Subclass\n”;} construct in Subclass ~Subclass() end! {cout<<“destruting Subclass”<<endl;} destruting Subclass }; destruting Base 23 destruting Base
19
C++语言程序设计
不恰当的虚函数
class Base {public: virtual void fn(int x) {cout<<“In Base class,int=”<<x<<endl;} }; class Subclass:public Base {public:virtual void fn(float x) {cout<<“in subclass,float x=”<<x<<endl;} };
C++语言程序设计 Chapter Twelve Polymorphism (第12章 多态性)
1
C++语言程序设计
Chapter 12
Polymorphism
Polymorphism(多态性) Virtual functions(虚函数) Pure virtual function(纯虚函数) Abstract class(抽象类)
重载是一项编译器技术,用来区分函 数名字相同但是参数列表不同的函数。 覆盖发生在继承的时候,当派生类的 成员函数与基类的成员函数的函数名 和参数列表都相同时便会发生覆盖。
13
C++语言程序设计
虚析构函数
虚 函 数
何时需要虚析构函数? 当你可能通过基类指针删除派生类对 象时 如果你打算允许其他人通过基类指针 调用对象的析构函数(通过delete这 样做是正常的),并且被析构的对象 是有重要的析构函数的派生类的对象, 就需要让基类的析构函数成为虚拟的。
20
C++语言程序设计
void test(Base &b) {int i=1; b.fn(i); float f=2.0; b.fn(f); } void main() {Base bc; Subclass sc; cout<<“calling test(bc)\n”; test(bc); cout<<“calling test(sc)\n”; test(sc); }
16
C++语言程序设计
例
纯 虚 函 数 与 抽 象 类
#include <iostream> using namespace std; class B0 //抽象基类B0声明 { public: //外部接口 virtual void display( )=0; //纯虚函数成员 }; class B1: public B0 //公有派生 { public: void display(){cout<<"B1::display()"<<endl;} //虚成员函数 }; class D1: public B1 //公有派生 { public: void display(){cout<<"D1::display()"<<endl;} //虚成员函数 };
抽象类
纯 虚 函 数 与 抽 象 类
作用
– 抽象类为抽象和设计的目的而建立,将有关的数 据和行为组织在一个继承层次结构中,保证派生 类具有要求的行为。 – 对于暂时无法实现的函数,可以声明为纯虚函数, 留给派生类去实现。
注意
– 抽象类只能作为基类来使用。
– 不能声明抽象类的对象。
– 构造函数不能是虚函数,析构函数可以是虚函数。
11
C++语言程序设计
When to use virtual functions
使用虚函数会涉及内存和执行时间开 销的问题,所以在选择一个基类函数 是否声明为虚函数时要慎重考虑。 一般而言,如果一个基类的成员函数 可能在派生类中被覆盖,那么就应将 其声明为虚函数。
12
C++语言程序设计
Overriding and overloading
– 函数重载 – 运算符重载
– 虚函数
静态:编译时的多态 动态:运行时的多态
3
C++语言程序设计
联编(binding)
联编:是指计算机程序自身彼此关联 的过程 静态联编:在编译连接阶段完成的 动态联编:在程序运行阶段完成的
4
C++语言程序设计
虚函数
虚 函 数
虚函数是动态联编的基础。 是非静态的成员函数。 在类的声明中,在函数原型之前写virtual。 virtual 只用来说明类声明中的原型,不能用在 函数实现时。 具有继承性,基类中声明了虚函数,派生类中 无论是否说明,同原型函数都自动为虚函数。 本质:不是重载声明而是覆盖。 调用方式:通过基类指针或引用,执行时会 根据指针指向的对象的类,决定调用哪个函数。
17
void fun(B0 *ptr) //普通函数 { ptr->display(); } void main() //主函数 { B0 *p; //声明抽象基类指针 B1 b1; //声明派生类对象 D1 d1; //声明派生类对象 p=&b1; fun(p); //调用派生类B1函数成员 p=&d1; fun(p); //调用派生类D1函数成员 }
calling test(bc) In Base class,int=1 In Base class,int=2 classing test(sc) In Base class,int=1
In Base class,int=2
21
C++语言程序设计
虚函数的限制
(1)只有类的成员函数才能说明为虚函数,因为 虚函数仅适用于继承关系的类对象,所以普通不 能说明为虚函数。 (2)内联函数不能是虚函数,因为内联函数是在 编译时决定其位置。 (3)构造函数不能是虚函数,因为构造时对象还 是一片未定型的空间。 (4)析构函数可以是虚函数,而且通常声明为虚 函数。 Void finishWithObject(Base *pHeapObject) {…… delete pHeapObject; }
C++语言程序设计
输出结果:
first: construct in Base second construct in Base construct in subclass calling test(bc) destructing base calling test(sc) destructing base end!
10
void fun(B0 *ptr) //普通函数 { ptr->display(); }
void main() //主函数 { B0 b0, *p; //声明基类对象和指针 B1 b1; //声明派生类对象 D1 d1; //声明派生类对象 p=&b0; fun(p); //调用基类B0函数成员 运行结果: p=&b1; fun(p); //调用派生类B1函数成员 B0::display() p=&d1; B1::display() fun(p); //调用派生类D1函数成员 D1::display() }