构造函数、析构函数、拷贝构造函数、赋值函数
2017-09-17 12:10
260 查看
1、基本声明:
构造函数:A (void);
析构函数:~A(void);
拷贝构造函数:A(const A& rhs);
赋值函数:A& operator(const A& rhs);
2、具体:
对于拷贝构造函数来说,还有一个浅拷贝和深拷贝的问题。对于静态分配分配到栈的内存,拷贝构造不会出问题,关键是分配到堆的内存(程序员new出来的对象),会出现两个指针指向同一块内存,然后析构的时候释放两次的问题(第一次可以,第二次就悬垂指针要翻皮水了)
例如:
看一下具体流程:对象a创建的时候调用构造函数,分配100个内存给p,再创建b,把a赋值给b,此时自己没有定义拷贝构造函数,编译器自己创建一个默认的拷贝构造函数(什么?上文没有?拷贝构造函数也是一种构造函数嘛。。),执行
怎么解决?其实就是在b创建的时候把p指向的内存不要在同一块,而是另外创建一个就好了,这样释放的时候指针就不会找不到对应的内存了。
就发生如下情况:
参考blog(写的是真的好):
http://blog.csdn.net/lwbeyond/article/details/6202256/
构造函数: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/
相关文章推荐
- 编写String类的普通构造函数、拷贝构造函数、析构函数、赋值函数
- String的构造函数,拷贝构造函数、析构函数和赋值函数
- string类的构造函数,拷贝构造函数,析构函数和赋值函数
- 写String类的普通构造函数,析构函数,拷贝构造函数和赋值函数
- 构造函数,拷贝构造函数,析构函数,赋值函数,关键字
- 编写类String 的构造函数、拷贝构造函数、析构函数和赋值函数
- 自主编程实现String类的构造函数,析构函数,拷贝构造函数,赋值函数
- 编写类String的构造函数、拷贝构造函数、析构函数、赋值函数
- 编写string类的构造函数、拷贝构造函数、析构函数、赋值函数
- string类构造函数、拷贝构造函数、赋值函数、析构函数
- String 构造函数,析构函数,拷贝构造函数和赋值函数
- 构造函数,拷贝构造函数,赋值函数,析构函数
- string类的构造函数、析构函数、拷贝构造函数和赋值函数
- 类String的 构造函数、拷贝构造函数、析构函数、赋值函数实现
- 构造函数、拷贝构造函数、赋值函数、析构函数的调用顺序
- 构造函数、析构函数、拷贝构造函数、赋值函数
- 实现MyString类--构造函数、拷贝构造函数、析构函数、赋值函数、操作符重载函数
- 编写String类的构造函数、析构函数、拷贝构造函数、赋值函数
- String 的普通构造函数、拷贝构造函数、析构函数、赋值函数
- c++笔记之赋值函数,拷贝构造函数,构造函数,析构函数