C++实现类设计一个类,包含构造函数析构函数顺序、析构函数等?

#include &iostream&
using namespace std;
class Person {
Person(string name, int age);
~Person();
string getName();
int getAge();
Person::Person() {
name = "ttf";
Person::Person(string name, int age):name(name),age(age) {
Person::~Person() {
cout && "释放了" && this-&getName() &&
string Person::getName() {
return this-&
int Person::getAge() {
return this-&
int main() {
cout && p.getName() && " " && p.getAge() &&
Person *person = new Person("fft", 21);
cout && person-&getName() && " " && person-&getAge() &&
使用new关键字,前面的必须是指针形式
析构函数释放内存的特点:
- 不管是堆中还是栈中,先创建的后释放,后创建的先释放
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:90923次
积分:2629
积分:2629
排名:第12286名
原创:176篇
转载:14篇
(1)(1)(1)(2)(1)(6)(31)(72)(43)(20)(2)(1)(7)(2)&&&&&&& 对于类对象成员的初始化我们始终是建立成员函数然后手工调用该函数对成员进行赋值的,那么c++中对于类来有没有更方便的方式能够在对象创建的时候就自动初始化成员变量呢,这一点对操作保护成员是至关重要的,答案是肯定的。关于C++类成员的初始化,有专门的构造函数来进行自动操作而无需要手工调用,在正式讲解之前先看看c++对构造函数的一个基本定义:&&&&&&&1,C++规定,每个类必须有默认的构造函数,没有构造函数就不能创建对象。&&&&&&&2,若没有提供任何构造函数,那么C++自动提供一个默认的构造函数,该默认构造函数是一个没有参数的构造函数,它仅仅负责创建对象而不做任何赋值操作。&&&&&& 3,只要类中提供了任意一个构造函数,那么C++就不在自动提供默认构造函数。&&&&&& 4,类对象的定义和变量的定义类似,使用默认构造函数创建对象的时候,如果创建的是静态或者是全局对象,则对象的位模式全部为0,否则将会是随即的。&&&&&& 构造函数的作用是在创建对象时,系统自动调用它来给所创建的对象初始化。构造函数是在类体中进行说明的一种特殊的成员函数。&&&&&& 构造函数的特点:&&&&&&&1,构造函数是一种成员函数,它的说明在类体内,它的函数体可以写在类体内,也可以写在类体外。&&&&&&&2,构造函数是一种特殊的成员函数,该函数的名字与类名相同。定义和说明构造函数时,不必指明函数类型。&&&&&& 3,构造函数可以有一个参数或多个参数,也可以没有参数。(在说明的时候也可以设置默认值0&&&&&& 4,构造函数可以进行重载。&&&&&& 5,构造函数多用于创建对象时系统自动调用,也可以在程序中调用构造函数创建无名对象。&&&&&&&默认构造函数的特点:&&&&&& 1,默认构造函数时无参数的构造函数。定义格式为:&类名& :: &默认构造函数名& ()&&& {&& & 函数体&&& }&&&&&&&2,默认构造函数名与该类的类名相同。&&&&&&&3,默认构造函数可以由用户定义,其格式如上所示。当类中没有定义任何构造函数时,系统将自动生成一个函数体为空的默认构造函数。&&&&&& 4,在程序中定义一个没有给定初始值的对象时,系统将自动调用默认构造函数创建该对象。当该对象是外部的或静态的时,它的所有数据成员被初始化为0或空,当该对象是走动的时,它的所有数据成员的值是无意义的。&&&&&&&拷贝构造函数的特点:&&&&&& 同一个类中的两个对象时,可以用一个已知的对象去创建另一个对象。由一个对象初始化另一个对象时,系统将自动调用拷贝构造函数或默认拷贝构造函数。&&&&&& 拷贝构造函数的特点:&&&&&& 1,拷贝构造函数名字与类名相同,并且不必指明返回类型。&&&&&&&2,拷贝构造函数只有一个参数,并且该参数是该类的对象的引用。&&&&&& 3,拷贝构造函数的定义格式为:&类名& :: &拷贝构造函数名&& ( &类名& & &引用名& )&&& {&& &函数体&& }&&&&&&&4,如果一个类中没有定义拷贝构造函数,则系统自动生成一个默认拷贝构造函数。该默认拷贝构造函数的功能是将已知对象的所有数据成员的值拷贝给未知对象的所有对应的数据成员。&&&&&& 拷贝构造函数的用处:&&&&&& 1,用已知的对象创建同一个类的新对象。&&&&&& 2,在使用对象作为函数参数时,当实参值传递给形参时,系统将自动调用拷贝构造函数来实现这一传递。&&&&&& 3,当对象作为函数的返回值时,系统自动调用拷贝构造函数用返回值或对象值创建一个临时对象,然后再将这个临时对象赋值给调用函数中的某个接收函数返回值的对象。&&&&&& 析构函数&&&&&&&析构函数用来释放一个对象。当一个对象结束它的生存期时,系统将自动调用析构函数来释放该对象。析构函数的作用正好与构造函数的作用相反。析构函数是在类体中进行说明的一种特殊的成员函数。&&&&&& 析构函数的特点:&&&&&&&1,析构函数是一种成员函数,它的函数体可以写在类体内,也可以写在类体外。&&&&&&&2,析构函数名与类名相同,与构造函数名的区别在于析构函数名前加“~”,表明它的功能与构造函数功能相反。&&&&&& 3,析构函数没有参数,不能重载,也不必指定函数类型,一个类中只能有一个析构函数。&&&&&& 4,析构函数通常是被系统自动调用的,在下面的情况中析构函数将被自动调用;&&&&&&&(1),当一个对象的生存期结束时,例如,在一个函数体内定义的对象,当该函数结束时,自动调用析构函数释放对象。&&&&&& (2),使用new运算符创建的对象,在使用delete运算符释放该对象时,系统将自动调用析构函数。&&&&&& 默认析构函数的特点:&&&&&& 如果一个类中没有定义析构函数时,系统将自动生成一个默认析构函数,格式为;&&&&&&&&类名&& :: ~&默认析构函数名&()&& {& }&&&&&& 默认析构函数与用户定义的析构函数具有相同的特点,其区别仅在于,默认析构函数是系统自动生成的,并且是一个空函数。&&&&&&&例一分析下面的程序题熟悉调用构造函数和析构函数;&span style=&font-size:18&&#include &iostream.h&//文件包含命令class Tdate//定义一个Tdate的类{ public://四个公有成员函数
Tdate(int y,int m,int d);//定义的带三个参数的构造函数 Tdate() { cout&&&Default Constructor called/n&;}//用户定义的默认构造函数 ~Tdate();//用户定义的析构函数 void Print();//一个无返回值的成员函数 private://两个三个私有数据成员
int year,month,};Tdate::Tdate(int y,int m,int d)//类体外构造函数的函数体{ year=y; month=m; day=d;
cout&&&Constructor called/n&&&d&&}Tdate::~Tdate()//类体外析构函数的函数体{ cout&&&Constructor called/n&&&day&&}void Tdate::Print()//类体外成员函数的函数体{ cout&&year&&&,&&&month&&&,&&&day&&}void main(){ static Tdate d1;//创建的一个静态的对象d1,这时调用默认构造函数,由于是静态的,数据成员的值均为0 Tdate d2();//创建一个自动类的对象d2,这时调用构造函数 cout&&&d1 is &;
d1.Print(); cout&&&d2 is &; d2.Print();}&/span&分析:(1)由于d1是静态的无初始值的对象,因此调用默认构造函数,输出Default Constructor called&&&&&&&&&(2)由于d2是由初始值的对象,因此调用构造函数,输出Constructor called 2&&&&&&& (3)由于d1是静态的对象,因此各个数据成员的值均为0,输出d1 is 0,0,0&&&&&&& (4)由于d2是初始化的对象,因此输出d2 is &&&&&&& (5)由于两个对象的生存期已结束,因此要调用析构函数来释放对象,释放对象遵循对象释放的顺序与创建的顺序相反,先创建的对象后释放,后创建的对象先释放,输出Constructor called 2和Constructor called 0&&&&& 例二熟悉调用拷贝构造函数的过程;&span style=&font-size:18&&#include &iostream.h&//文件包含命令class Tpoint//创建一个Tpoint的类{public://五个公有成员函数 Tpoint(int x,int y)//带参数的构造函数 { X=x; Y=y; } Tpoint(Tpoint &p);//带参数的拷贝构造函数 ~Tpoint()//用户定义的析构函数 { cout&&&Constructor called/n&; } int Xcoord()//类内带有函数体的成员函数 { return X; } int Ycoord() { return Y; }private://两个私有的数据成员 int X,Y;};Tpoint::Tpoint(Tpoint &p)//带有参数的拷贝构造函数的函数体{ X=p.X; Y=p.Y; cout&&&Copy-initialization Constructor called/n&;}void main(){ Tpoint p1(4,9);//创建一个带参数的对象 Tpoint p2(p1);//创建一个用已知的对象去初始化未知对象的对象 Tpoint p3=p2; cout&&&p3=(&&&p3.Xcoord()&&&,&&&p3.Ycoord()&&&)/n&;}&/span&分析:& (1)由于创建的对象p1带有参数,因此先调用构造函数进行初始化&&&&&&&&& (2)由于创建的对象p2是引用对象p1,因此调用拷贝构造函数,输出Copy-initialization Constructor called&&&&&&&&& (3)由于创建的对象p3也是引用对象p2,又一次调用拷贝构造函数,输出 Copy-initialization Constructor called&&&&&&&&& (4)初始化完毕后,输出类对象p3的坐标,输出p3=(4,9)&&&&&&&&& (5)当三个对象均结束生存期后,调用新构函数释放对象。输出三次 Constructor called&&&&& &&&&&&&
Linux-学习笔记(PHP向)&一&
最新教程周点击榜
微信扫一扫C++之衍生类的构造函数和析构函数 - C++当前位置:& &&&C++之衍生类的构造函数和析构函数C++之衍生类的构造函数和析构函数&&网友分享于:&&浏览:0次C++之派生类的构造函数和析构函数&&&&&&&&&&&&派生类的构造函数
&&&&&&&&派生类对象的数据结构由基类中说明的数据成员和派生类中说明的数据成员共同组成。在创建派生类的对象时,不仅要对派生类中说明的数据成员初始化,而且还要对基类中说明的数据成员初始化。由于构造函数不能被继承,因此,派生类的构造函数必须通过调用基类的构造函数来初始化基类中的数据成员。所以,在定义派生类的构造函数中,不仅要对自己数据成员进行初始化,还要包含调用基类的构造函数对基类中数据成员进行初始化。如果,派生类中海油子对象,还应包含调用对子对象初始化的构造函数。
&&&&&& 派生类的构造函数的定义格式:
&&&&&& &派生类构造函数名& (& &总参数表&& ): &基类构造函数名& ( &参数表1& )
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &子对象名&& ( &参数表2&& )....
&&&&&&&&&&&&&&&& &派生类数据成员初始化&
&&&&&& 其中,派生类构造函数名同派生类名。派生类构造函数的总参数表中的参数包括冒号后面的所有参数表中的参数的总和。在对基类中数据成员初始化时,调用基类的构造函数产生一个对象,将该对象存放到创建派生类对象时所占有的内存单元中,作为派生类对象成员一部分。在对子对象初始化时,调用子对象类的构造函数进行初始化。最后调用派生类构造函数的函数体内语句对派生类本身的数据成员初始化。也可以把对派生类数据成员的初始化操作放在成员初始化列表中,这是派生类构造函数可能成为空函数。
&&&&&& 派生类构造函数的调用顺序为:
&&&&&&&1,基类构造函数
&&&&&& 2,子对象类构造函数(如果有子对象的话)
&&&&&& 3,派生类构造函数
&&&&&&&派生类的析构函数
&&&&&&&由于析构函数也不能被继承,因此执行派生类的析构函数时,也要调用基类的析构函数。执行派生类的析构函数的顺序正好与执行派生类构造函数的顺序相反:
&&&&&& 1,先调用派生类的析构函数
&&&&&&&2,再调用派生类中子对象类的析构函数
&&&&&& 3,最后调用基类的析构函数
&&&&&&&用一个例子来说明调用顺序:
&span style=&font-size:18&&#include &iostream&
A()//定义的基类A的默认构造函数
{ a=0;cout&&&Default Constructor called.A\n&; }
A(int i)//定义的带一个参数的基类A的构造函数
cout&&&Constructor called.A\n&;
~A()//定义的基类A的析构函数
{ cout&&&Destructor called.A\n&; }
void Print()
{ cout&&a&&&,&; }
int Geta()
class B:public A//派生类B公有继承基类A
B()//派生类B的默认构造函数
{ b=0;cout&&&Default Constructor called.B\n&; }
B(int i,int j,int k);//说明的派生类B的构造函数
~B()//派生类B的析构函数
{ cout&&&Destructor called.B\n&; }
void Print()
A::Print();//说明基类A的成员函数
cout&&b&&&,&&&aa.Geta()&&//通过子对象调用基类A的成员函数
B::B(int i,int j,int k):A(i),aa(j),b(k)//派生类B的构造函数的函数体
cout&&&Constructor called.B\n&;
int main()
B bb[2];//定义的派生类B的对象数组
bb[0]=B(3,4,5);//通过派生类B对每个数组元素进行赋值
bb[1]=B(7,-8,9);
for(int i=0;i&2;i++)
bb[i].Print();//通过对象调用成员函数
&&&&&&&&&&&& 程序分析:
&&&&&& 1,前六行输出的是在创建派生类B的对象数组中的两个对象元素时调用派生类B的默认构造函数前先调用基类A的默认构造函数,创建一个数组元素调用两次基类A的默认构造函数,再调用一次派生类B的构造函数。因此输出结果中的前六行。
&&&&&&&2,接着输出的第七行到十八行是在调用派生类B的构造函数时创建临时对象时,再将临时对象赋值给数组对象元素,然后再调用析构函数将临时对象释放。因此,每赋值给一个数组对象元素时,都会创建一个临时对象,在创建临时对象的过程中,先调用两次基类A的构造函数,再调用一次派生类B的构造函数,然后释放临时对象时,先调用一次派生类B的析构函数,再调用两次基类A的析构函数。因此赋值给两个数组对象元素会输出七到十八行的结果。
&&&&&& 3,接着输出的两行数字是派生类B的对象数组的元素的数据值。
&&&&&& 4,最后六行输出的是释放对象数组bb的两个元素,每释放一个先调用一次派生类B的析构函数,再调用两次基类A的析构函数。释放两个元素,因此输出的结果如上。
&&&&&&&使用派生类构造函数应注意的事项:
&&&&&& 一,在基类中有默认构造函数或者没有定义任何构造函数时,派生类构造函数中隐含对基类默认构造函数的调用。
&span style=&font-size:18&&#include &iostream&
A()//定义的基类A的默认构造函数
A(int i)//定义的带一个参数的基类A的构造函数
void Print()
{ cout&&a&&&,&; }
class B:public A//派生类B公有继承基类A
B()//派生类B的默认构造函数
{ b1=b2=0; }
B(int i)//定义的派生类B的构造函数
{ b1=0; b2=i; }
B(int i,int j,int k):A(i),b1(j),b2(k)//赋值的派生类B的构造函数
void Print()
A::Print();//说明基类A的成员函数
cout&&b1&&&,&&&b2&&
int b1,b2;
int main()
B b1;//创建的无参数的对象
B b2(5);//创建的带一个参数的对象
B b3(1,2,3);//带三个参数的对象
b1.Print();
b2.Print();
b3.Print();
&&&&&&&&& 分析程序:
&&&&&&1,派生类B中有三个构造函数,前两个是隐含调用基类A中的默认构造函数,派生类B的第三个构造函数显式地调用了基类A中的一个带参数的构造函数。
&&&&& 2,输出的结果第一行0,0,0& 创建对象b1时调用派生类中的默认构造函数,并且在调用之前隐含调用了基类A的默认构造函数,因此输出这样的结果
&&&&& 3,输出的第二行0,0,5& 创建对象b2时调用派生类B中带一个参数的构造函数,在调用之前先隐含调用基类A中的默认构造函数,因此输出这样的结果。
&&&&&&4,输出的第三行1,2,3& 创建对象b3时调用派生类的第三个构造函数,在调用之前先显式调用了基类A中带一个参数的构造函数,因此输出这样的结果。
&&&&&二,当基类的构造函数使用一个或多个参数时,派生类的构造函数必须提供将参数传递给基类构造函数的途径。
&span style=&font-size:18&&#include &iostream&
A(int i,int j)
{ a1=i; a2=j; }
void Print()
{ cout&&a1&&&,&&&a2&& }
int a1,a2;
class B:public A//派生类B公有继承基类A
B(int i,int j,int k,int l,int m);
void Print()
A::Print();//说明基类A的成员函数
cout&&b&&&,&;
aa.Print();//通过对象引用成员函数
B::B(int i,int j,int k,int l,int m):A(i,j),aa(k,l),b(m)
int main()
B b1(1,2,3,4,5);
b1.Print();
&&&&&&&&& 简单的分析出:派生类B的构造函数带5个参数,前两个参数传递给基类A中的构造函数,中间两个参数传递给子对象aa的类A的构造函数,最后一个参数传递给派生类B的构造函数。
&&&&&& 输出的结果为: 1,2
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&5,3,4
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 1234567891011 Copyright & &&版权所有

我要回帖

更多关于 构造函数与析构函数 的文章

 

随机推荐