【一天一篇CPP】派生类的构造函数和析构函数
2013-10-10 14:29
393 查看
1.基类的构造函数是不能继承的,在声明派生类时,派生类并没有把基类的构造函数继承过来,但是可以通过一种显式的声明来调用基类的构造函数。
对于析构函数,系统会自动调用基类的析构函数,详细看下面的 “3注意点”。
2.构造函数调用的例子:
3.注意点:
A 派生类是先调用基类的构造函数,再构造派生类增加的成员。
B 对象释放时,基类的析构函数是自动被系统调用的,不用用户操刀。系统先调用派生类的析构函数,【然后是子对象的析构函数,】最后自动调用基类的析构函数。
4.有子对象的派生类的构造函数【子对象:对象的对象,它是类的对象,但充当另一个类的数据成员,如public: string str1;,而string本身是一个类】
如何为子对象构造呢,一个例子
这个例子中,派生类的构造函数包括三个部分:
A 通过基类的构造函数对基类成员进行初始化
B 通过子对象的构造函数对子对象数据成员进行初始化
C 对派生类增加的数据成员的初始化
形式总结:
派生类构造函数名( 总参数列表 ) : 基类构造函数名( 参数列表 ) , 子对象名【注意不是子对象的类名】( 参数列表 )
{派生类中新增加的数据成员的初始化,这些内容写到上一行也可以,请参照上门第一个例子}
其中若三者都写在第一行,三者的书写顺序可以改变,但是无聊如何改变,调用顺序仍然为:基类的构造函数、子对象的构造函数、新增成员的构造。
5.多层派生【派生完再派生,不是多继承的意思】和构造函数和析构函数
多层派生时的构造函数:
注意:
A 不要列出每一层派生类的构造函数,只要写出上一层派生类的构造函数即可。
B 系统会默认先构造最源头的基类,再初始化更分支的基类,最后是它自己的成员。【析构函数则相反】
6.派生类的构造函数的特殊形式
A 假如派生类 没有用户定义的构造函数 或 构造函数中没有对基类的构造函数进行显式调用 ,那么意味着系统默认隐含调用基类的默认构造函数【当然这个默认构造函数可能是系统生成的,也可能是用户定义的,系统只会在用户没有定义构造函数的时候生成默认构造函数,当不能生成则派生类构造出错】。例子如下:
在这个例子中若派生类自己增加的age变量不需要初始化,则可以省略它的构造函数!!
B 基类有且只有定义了带参数的构造函数【系统不会生成默认构造函数】,则在派生类中不能省略构造函数,且必须显式地调用基类的构造函数!【假如基类既有带参数的构造函数,又有没有参数的默认构造函数,则派生类的构造函数可以显式调用也可以不调用基类的构造函数】
C 以上A B 两点对基类适用,对子对象其实也适用。
对于析构函数,系统会自动调用基类的析构函数,详细看下面的 “3注意点”。
2.构造函数调用的例子:
#include <iostream> #include <string> using namespace std; class Student{ public: Student (int n, string nam,char s): num (n), name (nam),sex(s){}; public: int num; string name; char sex; }; class Student1: public Student { public: Student1(int n,string nam, char s,int a,string ad):Student(n,nam,s) { age = a; addr = ad; //当然也可以在上面写Student(n,nam,s),age(a),addr(ad) } public: int age; string addr; }; int main() { Student1 stud(1,"C雄",'m',20,"school"); cout << stud.num << " " << stud.name << " " << stud.addr<<endl; return 0; }
3.注意点:
A 派生类是先调用基类的构造函数,再构造派生类增加的成员。
B 对象释放时,基类的析构函数是自动被系统调用的,不用用户操刀。系统先调用派生类的析构函数,【然后是子对象的析构函数,】最后自动调用基类的析构函数。
4.有子对象的派生类的构造函数【子对象:对象的对象,它是类的对象,但充当另一个类的数据成员,如public: string str1;,而string本身是一个类】
如何为子对象构造呢,一个例子
#include <iostream> #include <string> using namespace std; class Student{ public: Student (int n, string nam): num (n), name (nam){}; public: int num; string name; }; class Student1: public Student { public: Student1(int n,string nam, int n1,string nam1, int a,string ad):Student(n,nam),monitor(n1,nam1) { age = a; addr = ad; //当然也可以在上面写Student(n,nam,s),age(a),addr(ad) } public: Student monitor; int age; string addr; }; int main() { Student1 stud(1,"C雄",2,"B雄",20,"school"); cout << stud.num << " " << stud.name << " " << stud.addr<< " " << stud.monitor.name<< endl; return 0; }
这个例子中,派生类的构造函数包括三个部分:
A 通过基类的构造函数对基类成员进行初始化
B 通过子对象的构造函数对子对象数据成员进行初始化
C 对派生类增加的数据成员的初始化
形式总结:
派生类构造函数名( 总参数列表 ) : 基类构造函数名( 参数列表 ) , 子对象名【注意不是子对象的类名】( 参数列表 )
{派生类中新增加的数据成员的初始化,这些内容写到上一行也可以,请参照上门第一个例子}
其中若三者都写在第一行,三者的书写顺序可以改变,但是无聊如何改变,调用顺序仍然为:基类的构造函数、子对象的构造函数、新增成员的构造。
5.多层派生【派生完再派生,不是多继承的意思】和构造函数和析构函数
多层派生时的构造函数:
#include <iostream> #include <string> using namespace std; class Student{ public: Student (int n, string nam): num (n), name (nam){}; int num; string name; }; class Student1 : public Student { public: Student1(int n,string nam, int a):Student(n,nam) { age = a; } int age; }; class Student2 : public Student1 { public: Student2(int n, char nam[10], int a, float s): Student1(n,nam,a) //这里突然把string ...改为 char ...[10]了,但是因为字符指针是可以赋值给string的,所以没问题 { score = s; } float score; }; int main() { Student2 std2(10,"C雄",20,80); cout << std2.num <<endl; cout << std2.name <<endl; cout << std2.age <<endl; cout << std2.score <<endl; return 0; }
注意:
A 不要列出每一层派生类的构造函数,只要写出上一层派生类的构造函数即可。
B 系统会默认先构造最源头的基类,再初始化更分支的基类,最后是它自己的成员。【析构函数则相反】
6.派生类的构造函数的特殊形式
A 假如派生类 没有用户定义的构造函数 或 构造函数中没有对基类的构造函数进行显式调用 ,那么意味着系统默认隐含调用基类的默认构造函数【当然这个默认构造函数可能是系统生成的,也可能是用户定义的,系统只会在用户没有定义构造函数的时候生成默认构造函数,当不能生成则派生类构造出错】。例子如下:
#include <iostream> #include <string> using namespace std; class Student{ public: Student (int n = 50, string nam = "C雄"): num (n), name (nam){}; int num; string name; }; class Student1 : public Student { public: Student1( int a) { age = a; } int age; }; int main() { Student1 std1(20); cout << std1.num <<endl; cout << std1.name <<endl; cout << std1.age <<endl; return 0; }//输出为50回车C雄回车20回车
在这个例子中若派生类自己增加的age变量不需要初始化,则可以省略它的构造函数!!
B 基类有且只有定义了带参数的构造函数【系统不会生成默认构造函数】,则在派生类中不能省略构造函数,且必须显式地调用基类的构造函数!【假如基类既有带参数的构造函数,又有没有参数的默认构造函数,则派生类的构造函数可以显式调用也可以不调用基类的构造函数】
C 以上A B 两点对基类适用,对子对象其实也适用。
相关文章推荐
- 【一天一篇CPP】inline、类的存储,简单的构造函数、析构函数
- 【一天一篇CPP】基类与派生类的转换(单向:从派生类赋值给基类,舍弃一部分)
- C++基础(九)继承与派生——派生类成员的构造函数和析构函数
- 【一天一篇CPP】多态性和虚函数和虚析构函数和纯虚函数和抽象类
- 【c++继承】继承关系中派生类对象构造函数和析构函数调用顺序
- 派生类的构造函数与析构函数
- c++派生类和基类的构造函数和析构函数
- C++学习之路—继承与派生(二):派生类的构造函数与析构函数
- C++ 派生类构造函数、析构函数调用 [大三TJB_708]
- C++中类的继承与Java中的不同,C++的派生类不能继承父类的构造函数和析构函数(不一定正确)
- 构造函数和析构函数在基类和派生类之间的调用顺序
- 包含析构函数和构造函数的程序.cpp
- C++语法基础--派生类的构造函数,赋值操作符,析构函数,虚析构函数
- C++:派生类的构造函数和析构函数
- 关于基类和派生类的构造函数和析构函数的执行顺序问题
- c++学习笔记4,派生类的构造函数与析构函数的调用顺序(一)
- C++语言基础 例程 派生类的构造函数和析构函数
- 第十一周阅读程序4:基类、派生类中构造函数、析构函数执行过程
- 4.5 派生类构造函数和析构函数的执行顺序举例
- 派生类的构造函数和析构函数(C++面向对象)