首页 > 代码库 > C++语言笔记系列之十五——派生类、基类、子对象的构造和析构函数调用关系
C++语言笔记系列之十五——派生类、基类、子对象的构造和析构函数调用关系
例子
example 1
注:若一个基类同时派生出两个派生类,即两个派生类从同一个基类继承,那么系统将为每一个简历副本,每个派生类独立地使用自己的基类副本(比如基类中有属于自己类的静态变量等)。
#include <iostream.h>
class Person
{
public:
person() {cout<<"Construction of person."<<endl;}
~person() {cout<<"Destruction of person."<<endl;}
};
class Student:public person
{
public:
student() {cout<<"Construction of student."<<endl;}
~student() {cout<<"Destruction of student."<<endl;}
};
class Teacher:public Person
{
public:
Teacher() {cout<<"Construction of teacher."<<endl;}
~Teacher() {cout<<"Destruction of teacher."<<endl;}
};
int main()
{
Student s;
Teacher t;
}
程序输出:
Construction of person.
Construction of student.
Construction of person.
Construction of teacher.
Destruction of teacher.
Destruction of person.
Destruction of student.
Destruction of person.
结论:若一个程序中有多个对象,每个对象必须按照顺序创建,在创建派生类对象时,调用构造函数的顺序为:基类构造-->子对象构造-->派生类构造。析构函数的调用顺序严格与构造函数相反。在派生类的构造函数中,当基类的构造函数缺省参数时,在派生类构造函数中可以缺省对基类构造函数的调用。
example 2
#include <iostream.h>
class Data
{
public:
Data(int x) {Data::x = x; cout<<"Data construction."<<endl;}
~Data() {cout<<"Data destruction."<<endl;}
private:
int x;
};
class Base
{
public:
Base(int x):d1(x) {cout<<"Base construction."<<endl;}
~Base() {cout<<"Base destruction."<<endl;}
private:
Data d1;
};
class Device:public Base
{
public:
Device(int x):Base(x), d2(x) //参数共用
{cout<<"Device construction."<<endl;}
~Device() {cout<<"Device destruction."<<endl;}
private:
Data d2;
};
int main()
{
Device obj(5);
}
程序输出:
Data construction.
Base construction.
Data construction.
Device construction.
Device destruction.
Data destruction.
Base destruction.
Data destruction.
构造顺序分析:调用Base类构造,而Base中含有子对象d1,所以要先调用d1的构造函数再调用Base的构造函数;Base构造函数调用完成之后再调用d2的构造;最后一步是调用派生类的构造。
example 3
class Base
{
public:
Base(int xx = 0):x(xx) //注意没有分号,等价于普通的构造函数类型
{cout<<"Base construction."<<endl;} //这个花括号是不能省略的
~Base() {cout<<"Base destrcution."<<endl;}
void print() {cout<<x<<",";}
int Getx() {return x;}
private:
int x;
};
class Device:public Base
{
public:
Device(itn xx = 0, int yy = 0):Base(xx), y(yy), z(xx+yy)
{cout<<"Device construction."<<endl;}
~Device() {cout<<"Device destruction."<<endl;}
void print()
{
Base::print();
cout<<y<<","<<z.Getx()<<endl;
}
private:
int y;
Base z;
};
int main()
{
Device obj1(1), obj2(4, 6);
obj1.print();
obj2.print();
}
程序输出:
Base construction.
Base construction.
Device construction.
Base construction.
Base construction.
Device construction.
2,0,2
4,6,10
析构略......
example 1
注:若一个基类同时派生出两个派生类,即两个派生类从同一个基类继承,那么系统将为每一个简历副本,每个派生类独立地使用自己的基类副本(比如基类中有属于自己类的静态变量等)。
#include <iostream.h>
class Person
{
public:
person() {cout<<"Construction of person."<<endl;}
~person() {cout<<"Destruction of person."<<endl;}
};
class Student:public person
{
public:
student() {cout<<"Construction of student."<<endl;}
~student() {cout<<"Destruction of student."<<endl;}
};
class Teacher:public Person
{
public:
Teacher() {cout<<"Construction of teacher."<<endl;}
~Teacher() {cout<<"Destruction of teacher."<<endl;}
};
int main()
{
Student s;
Teacher t;
}
程序输出:
Construction of person.
Construction of student.
Construction of person.
Construction of teacher.
Destruction of teacher.
Destruction of person.
Destruction of student.
Destruction of person.
结论:若一个程序中有多个对象,每个对象必须按照顺序创建,在创建派生类对象时,调用构造函数的顺序为:基类构造-->子对象构造-->派生类构造。析构函数的调用顺序严格与构造函数相反。在派生类的构造函数中,当基类的构造函数缺省参数时,在派生类构造函数中可以缺省对基类构造函数的调用。
example 2
#include <iostream.h>
class Data
{
public:
Data(int x) {Data::x = x; cout<<"Data construction."<<endl;}
~Data() {cout<<"Data destruction."<<endl;}
private:
int x;
};
class Base
{
public:
Base(int x):d1(x) {cout<<"Base construction."<<endl;}
~Base() {cout<<"Base destruction."<<endl;}
private:
Data d1;
};
class Device:public Base
{
public:
Device(int x):Base(x), d2(x) //参数共用
{cout<<"Device construction."<<endl;}
~Device() {cout<<"Device destruction."<<endl;}
private:
Data d2;
};
int main()
{
Device obj(5);
}
程序输出:
Data construction.
Base construction.
Data construction.
Device construction.
Device destruction.
Data destruction.
Base destruction.
Data destruction.
构造顺序分析:调用Base类构造,而Base中含有子对象d1,所以要先调用d1的构造函数再调用Base的构造函数;Base构造函数调用完成之后再调用d2的构造;最后一步是调用派生类的构造。
example 3
class Base
{
public:
Base(int xx = 0):x(xx) //注意没有分号,等价于普通的构造函数类型
{cout<<"Base construction."<<endl;} //这个花括号是不能省略的
~Base() {cout<<"Base destrcution."<<endl;}
void print() {cout<<x<<",";}
int Getx() {return x;}
private:
int x;
};
class Device:public Base
{
public:
Device(itn xx = 0, int yy = 0):Base(xx), y(yy), z(xx+yy)
{cout<<"Device construction."<<endl;}
~Device() {cout<<"Device destruction."<<endl;}
void print()
{
Base::print();
cout<<y<<","<<z.Getx()<<endl;
}
private:
int y;
Base z;
};
int main()
{
Device obj1(1), obj2(4, 6);
obj1.print();
obj2.print();
}
程序输出:
Base construction.
Base construction.
Device construction.
Base construction.
Base construction.
Device construction.
2,0,2
4,6,10
析构略......
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。