今天抽个空和大家分享下关于构造函数和析构函数的一些基本特点,顺便在书上抄了几个例子,对于我来说理解起来可能更容易一点,大神不说,和我一样是菜鸟的肯定有帮助。今天的内容不太多,最近我课有点多老是说整理整理,一直拖到现在了。这篇整理了快两个小时了,后面那都有点犯迷糊了,各位大神要是看到有什么错别字啊之类的,别骂我哈,那可能是周公送我的礼物。
析构函数
//析构函数
#include <iostream>
using namespace std ;
class Cars{
public :
Cars();//构造函数声明
void show ();
~Cars();//析构函数声明
private :
int wheels ;
int doors;
int speed;
char * car_name;//指针类型为char*,指向类型为char 指向地址????
};
Cars::Cars()//构造函数的定义
{
wheels=4;
doors=4;
speed=60;
car_name =new char [10];
}
Cars::~Cars()
{
delete[] car_name;//释放堆空间
cout<<"destructed"<<endl;
}
void Cars::show()
{
cout <<"wheels:"<<wheels<<endl;
cout<<"doors:"<<doors<<endl;
cout<<"speed:"<<speed<<endl;
}
int main ()
{
{
Cars car;
car.show();
}
cout <<endl;
Cars pud;
pud.show();
return 0;
}
输出的结果为:
wheels:4
doors:4
speed:6
destructed//作用域结束时自动调用析构函数
wheels:4
doors:4
speed:6
destructed//作用域结束时自动调用析构函数
析构函数没有返回值类型,没有参数,没有显示调用,并且它的函数名是在构造函数名前加一个“~”。析构函数的特点如下:
(1)析构函数与构造函数同名,且前面家“~”。
(2)析构函数没有返回值类型,不能有参数,也不能重载,一个类必须有也只能有一个析构函数。
(3)析构函数不能显示调用,他在类的生命周期结束时自动调用。
通常有这几种情况下析构函数会被自动调用:
(1).在显示撤销对象时系统会自动调用析构函数
(2).当一个对象被定义在一个函数体内,则当这个函数结束时,系统会自动调用析构函数。
(3).如果一个对象在使用new运算符动态生成时,那么使用delete运算符释放他时,会自动调用析构函数。
带参数的构造函数
前边所说的并不能满足对象初始化的要求,构造函数只是千篇一律的为对象中的和数据成员初始化同样的值,这对于面向对象的多样化来说并不适用。
为了使构造函数能根据不同的对象为其数据成员初始化不同的初值,面向对象中引入了带参数的构造函数。
如下:
//带参数的构造函数
#include<iostream>
using namespace std;
class student
{
private :
char *name;
int age;
int grade ;
public :
student(char * x,int y,int z)//带参数的构造函数,其目的是使用参数的值对对象中的成员变量赋初值
{
name =x;
age=y;
grade=z;
}
void show()
{
cout<<"name :"<<name<<endl;
cout <<"age :"<<age <<endl;
cout<<"grade :"<<grade<<endl;
}
};
int main ()
{
student zhang ("zhang",15,2);//具有带参数构造函数的类对象的声明方法。
student li("li",16,3);
student wang ("wang",14,2);
zhang.show();
cout<<endl;
li.show();
cout<<endl;
wang.show();
return 0;
}
程序输出结果为:
name:zhang
age:15
grade:2
name:li
age:16
grade:3
name:wang
age:14
grade:2
由此,利用带参数的构造函数可以对象的多样性,根据不同的对象及其参数表可以实现为其不同的数据成员进行不同的初始化。
重载构造函数
构造函数与一般的类成员函数一样均可被重载,构造函数函数通过参数的类型与个数的不同而进行重载,那些重载的构造函数之间通过他们所带参数的个数和类型进行区分。
//重载构造函数
#include <iostream>
using namespace std ;
class Date
{
private :
int year;
int month ;
int day;
public :
Date (int x=2006,int y=1,int z=1)
{
year =x;
month=y;
day=z;
}
void show ()
{
cout <<"this days:"<<year<<"."<<month<<"."<<day<<endl;
}
};
int main ()
{
Date day1;
day1.show();
Date day2(2005);
day2.show();
Date day3(2005,6);
day3.show();
Date day4(2016,3,6);
day4.show();
return 0;
}
输出结果为:
this days:2006.1.1
this days:2005.1.1
this days:2005.6.1
this days:2016.3.6
拷贝构造函数
拷贝函数和构造函数一样,当没有显示的给出时,系统会自动提供一个默认的拷贝构造函数来完成同类型对象间的复制工作。
例如:
//拷贝构造函数
#include <iostream>
using namespace std ;
class point {
private :
int x;
int y;
public :
point (int i,int j)//构造函数
{
x=i;
y=j;
cout <<"construction"<<endl;
}
point (const point &p)//只有一个参数,同类型对象的引用(传址)
{
x=p.x+10;
y=p.y+10;
cout <<"copy construction "<<endl;
}
void show()
{
cout<< "the point is :"<<"("<<x<<"."<<y<<")"<<endl;
}
};
int main ()
{
point a(10,20);
a.show();
point b(a);//使用“代入”法调用拷贝构造函数
b.show();
point c=b;//使用“赋值”法调用拷贝构造函数
c.show();
return 0;
}
输出结构为:
construction
The point is:(10,20)
copy construction
The point is:(20,30)
copy construction
The point is:(30,40)
从上面的例子中可以知道拷贝函数的一些特点:
(1)拷贝函数属于构造函数的一种,函数名必须与类名相同,且没有返回值类型。
(2)拷贝函数有且只有一个参数,并且是同类型函数 的一个引用。
(3)每一个类应该具有一个拷贝构造函数,可以根据具体的需要自行定义拷贝构造函数。如果没有显示的定义拷贝构造函数,系统会自动的生成一个默认的拷贝构造函数。
与一般构造函数一样,拷贝构造函数没有返回值,注意拷贝构造函数的参数一定是同类型对象的引用(即传的是物理地址)。
拷贝构造函数会在以下几种情况下会被调用:
(1).当类的一个对象初始化该类的另一个对象时;
(2).如果函数的形参是类的对象,调用函数进行形参和实参的结合时;
(3).如果函数的返回值是类的对象,函数调用完成返回时;
想知道更多有关于C++,请看后续内容…………………