您的位置:首页 > 编程语言 > C语言/C++

构造函数、析构函数、拷贝构造函数、赋值函数

2017-09-17 12:10 260 查看
1、基本声明:

构造函数:A (void);

析构函数:~A(void);

拷贝构造函数:A(const A& rhs);

赋值函数:A& operator(const A& rhs);

2、具体:

#include <iostream>
using namespace std;

class Area
{
public:
//构造函数
/*默认构造函数,如果类没有定义构造函数,则编译器会自动生成一个默认构造函数,仅用于生
成对象而没有赋值操作如果定义了有参数的构造函数,而且程序员也没有手动定义默认构造函数,
则不会自动生成默认构造,这时候定义对象初始化必须有参数,不然匹配不到相应的函数*/
Area()
{
len = 0;
wid = 0;
}
/*构造函数初始化列表,注意列表可以len(x), wid(len),但最好别用。另外,初始化列表需
要根据类成员的定义顺序来初始化*/
Area(int x, int y): len(x), wid(y){}
//这种如果参数是类类型则需要调用到重载的 "="
Area(int x, int y)
{
len = x;
wid = y;
}

/*析构函数,它没有返回类型,没有参数,不能随意调用,也没有重载,只有在类对象的生命
期结束的时候,由系统自动调用。
析构函数可以为虚函数, 用于继承的时候析构子类对象时会顺便把父类的也析构了*/
~Area();

/*拷贝构造函数,一种特殊的构造函数(函数名和类名相同,无返回值,都用于初始化呀)
有三种情况需要调用拷贝构造函数:函数形参为对象,函数返回值为对象,还有对象创建时的初始化。*/
Area(const Area& rhs)
{
len = rhs.len;
wid = rhs.wid;
}
//函数形参为对象
void copy_construct1(Area a)
{
cout << "object come in as formal parameter" << endl;
}
//函数返回值为对象
Area copy_construct2()
{
cout << "return value is an object" << endl;
Area a;
return a;
}

/*赋值函数,=运算符的重载,跟拷贝构造函数很像,区别在于下边这个不用于初始化,
而是用于赋值(两者不可混为一谈,对于基本类型两者差别不大,但是对于自定义的对象,
(1)初始化,只是单纯的分配内存给值,(2)赋值操作,需要分配内存,用中间值保存,
抹除对象原来的值,再把值填进去,资源消耗比较大,所以最好使用初始化)*/
Area& operator=(const Area& rhs)
{
len = rhs.len;
wid = rhs.wid;
}

private:
int len;
int wid;
};

int main()
{
Area a;     //默认构造,如果没有主动定义 && 定义了有参数的构造函数,这里就会出错

Area b(10, 10);     //带参数的构造函数

Area c(b);          //拷贝构造函数,这里是初始化
copy_construct1(c);     //对象作为参数
Area temp = copy_construct2();      //对象作为返回值

Area d;
d = b;              //赋值函数

return 0;
}


对于拷贝构造函数来说,还有一个浅拷贝和深拷贝的问题。对于静态分配分配到栈的内存,拷贝构造不会出问题,关键是分配到堆的内存(程序员new出来的对象),会出现两个指针指向同一块内存,然后析构的时候释放两次的问题(第一次可以,第二次就悬垂指针要翻皮水了)

例如:

class Area
{
public:
Area()
{
p = new int(100);
}
~Area()
{
if(p != NUll)
delete p;
}
private:
int *p;
}

int main()
{
Area a;
Area b(a);
return 0;
}


看一下具体流程:对象a创建的时候调用构造函数,分配100个内存给p,再创建b,把a赋值给b,此时自己没有定义拷贝构造函数,编译器自己创建一个默认的拷贝构造函数(什么?上文没有?拷贝构造函数也是一种构造函数嘛。。),执行
b.p = a.p
,就是说a和b的p指针都指向同一块内存



怎么解决?其实就是在b创建的时候把p指向的内存不要在同一块,而是另外创建一个就好了,这样释放的时候指针就不会找不到对应的内存了。

class Area
{
public:
Area()
{
p = new int(100);
}
Area(const Area& rhs)//这里这里这里
{
p = new int(100);
*p = *(rhs.p);   //把内容物都移过来
}
~Area()
{
if(p != NUll)
delete p;
}
private:
int *p;
}

int main()
{
Area a;
Area b(a);
return 0;
}


就发生如下情况:



参考blog(写的是真的好):

http://blog.csdn.net/lwbeyond/article/details/6202256/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++默认函数
相关文章推荐