构造函数和析构函数
一、构造函数
- 构造函数是类的一种特殊成员,本质上也是类的成员函数。
- 函数名和类名相同,没有返回类型,可以有参数。
- 当创建类的一个新对象时,构造函数被自动调用,完成对象的初始化工作。
构造函数初始化成员的两种方式:
- 赋值语句初始化
Clock(int h, int m, int s)
{
Hour = h;
Minute = m;
Seeond = s;
}
- 表达式表的方式初始化(括号内表示所要初始化的参数)
Clock(int h, int m, int s): Hour(h), Minute(m), Second(s)
{
}
例子:
例
class Counter{
private:
int value;
public:
Counter(int v):value(v){}
.....
};
class Clock{
private:
int Hour, Minute, Second;
public:
Clock(int h, int m, int s);
.....
};
void main( ){
Counter cOunter1 (8);//以函数形式初始化
Counter counter2=9;//赋值语句的方式初始化(这种方式只能用于只有一个参数的对象初始化)
Clock clock1(3, 5, 1);
//Clock clock2( ); 此种方式不可行,必须有三个参数,否则编译会出错
}:
重载构造函数
- 一个类可以提供多个构造函数,即构造函数的重载。
- 重载的目的是为了满足不同的初始化需要。
class Clock{
private:
int Hour, Minute, Second;
public:
Clock(int h, int m, int s);
Clock();
Clock(char* timestr);
.....
};
具有缺省参数的构造函数
- 构造函数也可以有缺省参数。如果在类外实现该函数时,就不能 再说明缺省值了。
class Clock{
private:
int Hour, Minute, Second;
public:
Clock(int h=0, int m=0, int s=0);
Clock(char* timestr);
//Clock();此时该种函数不能出现,编译器无法区分
.....
};
缺省的构造函数
- 对于没有构造函数的类,编译器将会自动为它生成一个没有参数的构造函数,该函数不做任何工作。
二、析构函数
- 与构造函数相对的是析构函数,C++通过析构函数来处理对象被销毁时的清理工作。
- 析构函数没有返回类型,没有参数,函数名是在类名前加~
- 析构函数将会在对象的生存期结束后被自动调用。
- 如果没有进行显式说明,编译器将会生成一个不做任何事的缺省的析构函数。
class Clock{
private:
int Hour, Minute, Second;
public:
Clock(int h=12, int m=0, int s=0);
~Clock();
.....
};
Clock::~Clock( ){cout<< "Clock obj destroyed!" < <endl;}
析构函数的典型用法
class CString{
private:
int len;
char *buf;
public:
CString(int n);
~ CString()
void copy(char *src);
};
CString::CString(int n){
len=n;
buf=new char[n];
}
void CString::copy(char *src){
strcpy(buf,src);
}
CString:~ CString(){
delete []buf;
动态内存管理容易出错的几个点:
●1.删除动态内存失败
●2.读写已删除的对象。
●3.对同一个内存空间使用两次delete.
(1) 2个及以上的指针指向同一个动态分配的对象
(2) 一个指针,多次删除
三、拷贝构造函数
- 如果将与自己同类的对象的引用作为参数进行构造函数 的初始化时,该构造函数就称为拷贝构造函数。
- 拷贝构造函数的特点:
1)首先,它是一个构造函数,当创建对象时系统会自动调用它。
2)其次,它将一一个已经创建好的对象作为参数,根据需要将该 对象中的数据成员逐一对应地赋值给新对象。
class Point{
private:
float x,y;
public:
Point(float a, float b){
x=a;y=b;
}
Point(Point &obj){
x=obj.x;
y=obj.y;
}
};
void main(){
Point obj1(5,15);
//调用Point(float,float)
Point obj2(obj1);
//调用Point(Point&)
Point obj3=obj2;
//调用Point(Point&)
}
缺省的拷贝构造函数
- 如果没有定义拷贝构造函数,那么编译器会为该类产生一个缺省 的拷贝构造函数。
- 缺省的拷贝构造函数使用位拷贝的方法来完成对象到对象的复制。
将第一个对象中的数据成员的值原封不动拷贝到第二个对象的数据成员中
例子:
class Point{
private:
float x, y;
public:
Point(float a, float b){
x=a; y=b;
}
};
void main()
{
Point obj1( 5, 15); //调用A(float, float)
Point obj2(obj1); //调用缺省的拷贝构造函数
Point obi3=obj2; //调用缺省的拷贝构造函数
}
缺省的拷贝构造函数的缺点
在大多数情况下,缺省拷贝构造函数工作得很好,但在
一些特殊的场合, 它的表现将不尽人意。
网上相关资料:
https://www.runoob.com/cplusplus/cpp-constructor-destructor.html