第五章构造函数调用顺序

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

对象成员初始化
#include <iostream> #include <string> using namespace std; class A { public: A(int a){cout<<"constructor of A"<<endl;} }; class Derive { public: A a; Derive() :a(10){cout<<"constructor of derive"<<endl;} };
//Derive(int value) :Base(value){cout<<"constructor of derive"<<endl;}
派生类构造函数的一般格式
派生类名(派生类构造函数总参数表) 基类构造函数(参数表1) 派生类名(派生类构造函数总参数表) :基类构造函数(参数表 ), 对象成员名(参数表2) 对象成员名(参数表 ) { 派生类中数据成员初始化 } 注意: 注意: (1)调用基类构造函数,应该用基类名; )调用基类构造函数,应该用基类名; (2)调用对象成员的构造函数,应该用对象成员的名字。 )调用对象成员的构造函数,应该用对象成员的名字。
基类构造函数的调用
class Base { public: Base(int b){cout<<"constructor of Base"<<endl;} }; class Derive:public Base { public: Derive() :Base(10){cout<<"constructor of derive"<<endl;} }; int main() { return 0; }
//Derive(int value) :a(value){cout<<"constructor of derive"<<endl;}
基类构造函数的调用
class Base { public: Base(int b){cout<<"constructor of Base"<<endl;} }; 编译错误,基类成员不 class Derive:public Base 能够被初始化。 { public: Derive(){cout<<"constructor of derive"<<endl;} }; int main() { return 0; }
完整的写法
int main() #include <iostream> #include <string> { using namespace std; return 0; class A } { public: A(int a){cout<<"constructor of A"<<endl;} }; class Base { public: Base(int b){cout<<"constructor of Base"<<endl;} }; class Derive:public Base { public: A a; Derive():Base(10),a(10){cout<<"constructor of derive"<<endl;} }; Derive(int v_a,int v_b): Base(v_a),a(v_b){cout<<"constructor of derive"<<endl;}
类型适应的使用场合
1、函数参数传递; 2、指针赋值。 Apple *app; Fruit *fru; fru=app; // app=fru; //谁对?谁不对? 注意:类型适应是面向对象多态性的很好 体现,是面向对象的程序具有了很强的 灵活性。但只有用指针才能体现。
课后习题
1、请描述基类、派生类、对象成员的构造 和析构顺序。 2 2、
不同继承方式的基类和派生类特性
继承方式 基类特性 public 公有继承 protected private public 私有继承 protected private public 保护继承 protected private 派生类特性 public protected 不可访问 private private 不可访问 protected protected 不可访问
C++语言的继承格式
单继承的定义格式如下: class 派生类名:继承方式 基类名 派生类名: { public: : members; //派生类新定义成员 ; 派生类新定义成员 private: : members; //派生类新定义成员 ; 派生类新定义成员 protected: : members; //派生类新定义成员 ; 派生类新定义成员 }; ; 其中,派生类名 是新定义的一个类的名字,它是从<基类名>中派生 的,并且按指定的 继承方式 派生的。 继承方式 常作用如下三 种关键字给予表示: public:公有继承; private:私有继承,可默认声明; protected:保护继承。
基类构造函数 基类析构函数
类对象构造函数
类对象析构函数
自身的构造
Baidu Nhomakorabea自身的析构
应注意的问题
在实际应用中,使用派生类构造函数时应注意如 下几个问题: (1)派生类构造函数的定义中可以省略对基类构 造函数的调用,其条件是在基类中必须有默认的构造 函数或者根本没有定义构造函数。当然,基类中没有 定义构造函数,派生类根本不必负责调用基类构造函 数。 (2)当基类的构造函数使用一个或多个参数时, 则派生类必须定义构造函数,提供将参数传递给基类 构造函数途径。在有的情况下,派生类构造函数体可 能为空,仅起到参数传递作用。
(1)在公有继承时,派生类的成员函数可 以访问基类中的公有成员和保护成员。 (2)在私有继承时,基类的成员只能由直 接派生类访问,而无法再往下继承。 (3)对于基类中的私有成员,只能被基类 中的成员函数和友元函数所访问,不能被其他 的函数访问。
思考
class A{ public: int pub_value_A; private: int pri_value_A; protected: int pro_value_A; }; class B:public A{ }; class C:private A{ };
{
A public B void main() B *obj_b=new B; obj_b->pub_value_A=10; obj_b->pro_value_A=20; obj_b->pri_value_A=30; C *obj_c=new C; obj_c->pub_value_A=10; obj_c->pro_value_A=20; obj_c->pri_value_A=30; } private C
苹果皮 果皮箱 水果皮 苹果皮箱
类型适应
• 类型适应是指两种类型之间的关系。例如,B类型适应A类型是 指B类型的对象能够用于A类型的对象所能使用的场合。 派生类的对象可以用于基类对象所能使用的场合,我们说派生类 适应于基类。同样道理,派生类对象的指针和引用也适应于基类 对象的指针和引用。 子类型化与类型适应是致的。B类型是A类型的子类型,那么B类 型必将适应于A类型。 子类型的重要性就在于减轻程序人员编写程序代码的负担。因为 一个函数可以用于某类型的对象,则它也可以用于该类型的各个 子类型的对象,这样就不必为处理这些子类型的对象去重载该函 数。
继承机制下的构造和析构函数
#include <iostream> int main() #include <string> { using namespace std; return 0; class A } { public: A(int a){cout<<"constructor of A"<<endl;} }; class Base { public: Base(int b){cout<<"constructor of Base"<<endl;} }; class Derive:public Base { public: A a; Derive(){cout<<"constructor of derive"<<endl;} };
类型适应
1、什么是类型适应? 例: #include <iostream.h> int function(int para){return para;} void main() { float a=10.5; cout<<function(a); }//对?不对???
A
B
void func( A *para){} B * b_obj; func(b_obj); //对?不对??? void func2(B * para){} A *a_obj; func2(a_obj); //对?不对???
继承机制下的构造和析构函数
构造函数的义务: (1)每个类必须负责自己的对象成 员初始化, (2)构造函数不能够被继承,派生 类的构造函数还必须调用基类的构造函 数来初始化基类成员;
对象成员初始化
#include <iostream> #include <string> using namespace std; class A { public: A(int a){cout<<"constructor of A"<<endl;} }; class Derive 编译错误,对象成员a { public: 不能够被初始化。 A a; Derive(){cout<<"constructor of derive"<<endl;} };
派生类的三种继承方式
1. 公有继承(public)。 公有继承( ) 公有继承的特点是基类的公有成员和保护成员作 为派生类的成员时,它们都保持原有的状态,而基类 的私有成员仍然是私有的。 2. 私有继承(private)。 私有继承( ) 私有继承的特点是基类的公有成员和保护成员作 为派生类的私有成员,并且不能被这个派生类的子类 访问。 3. 保护继承(protected)。 保护继承( ) 保护继承的特点是基类的所有公有成员和保护成 员都成为派生类的保护成员,并且只能被它的派生类 成员函数或友元访问,基类的私有成员仍然是私有的。
继承中构造、析构函数的调用顺序
如果派生类和基类都有构造函数,在定义一派生 类时,系统首先调用基类的构造函数,然后再调用派 生类的构造函数。在继承关系下有多个基类时,基类 构造函数的调用顺序取决于定义派生类时基类的定义 顺序。 由于析构函数也不能被继承,因此在执行派生类 的析构函数时,基类的析构函数也将被调用。执行顺 序是先执行派生类的析构函数,再执行基类的析构函 数,其顺序与执行构造函数时的顺序正好相反。
相关文档
最新文档