C++ Primer笔记9_构造函数_拷贝构造(深拷贝与浅拷贝)
来源:互联网 发布:淘宝客营销软件 编辑:程序博客网 时间:2024/05/16 06:50
1.构造函数:
>构造函数是一个特殊的、与类同名的成员函数,用于给每个成员设置适当的初始值。
>构造函数不能有返回值,函数名与类名相同。
>缺省构造函数时,系统将自动调用该缺省构造函数初始化对象,缺省构造函数会将所有数据成员都初始化为零或 空。缺省构造函数是不带参数的构造函数。
>创建一个对象时,系统自动调用构造函数。
构造函数的特点:
1.构造函数可以重载,传入什么实参决定调用不同版本的构造函数。
2.构造函数不能声明为const 、也不能声明为virtual;(析构函数可以)
3.一个类如果自定义了一个构造函数,编译器就不会生成默认构造函数。
4.只有构造函数才有类似初始化列表的形式来初始化成员变量(特别是const成员变量只能在初始化列表中初始化)
例子:
#include <iostream>#include <new>class Person{public:Person();//默认的构造函数Person(int n, const string &str);//构造函数的重载private:int age;string *name;};
2.拷贝构造
先介绍一下深拷贝与浅拷贝:
>浅拷贝: 指的是在对象复制时,只对对象中的数据成员进行简单的赋值;默认拷贝构造函数执行的也是浅拷贝。 大多情况下“浅拷贝”已经能很好地工作了,但是一旦对象存在了动态成员,那么浅拷贝就会出问题了。
>深拷贝:当类的成员变量有指针类型时,拷贝对象时应该为指针变量重新分配好空间,避免浅拷贝中只拷贝指针的 值,使得两个指针指向同一块内存空间。
浅拷贝缺陷例子:
#include <iostream>#include <new>using namespace std;class Person{public:Person();Person(int n, const string &str);//构造函数重载~Person();private:int age;string *name;};Person::Person():age(0), name(NULL)//构造函数初始化列表,定义时不必写!{cout << "Default Person" << endl;}Person::Person(int n, const string &str):age(n), name(new string(str)){cout << "Init Person" << endl;}Person::~Person(){if(name){cout << "~Person " << "name: " << *name << " age: " << age << endl;}delete name;}int main(){Person p1(10, string("SCOTT"));Person p2 = p1;return 0;}
运行结果:
Init Person
~Person name: SCOTT age: 10
Segmentation fault (core dumped)
程序崩溃原因:
p2由p1初始化而得到,由于我们没有自定义拷贝构造函数,所以调用的是默认的拷贝构造函数,属于浅拷贝,只对name的值进行了拷贝;p1与p2中的name指针指向同一个new空间,最后调用析构函数时,会造成两次delete而出现段错误。
如下图所示:
解决方法:自定义拷贝构造函数! 达到深拷贝的效果
深拷贝例子:
#include <iostream>#include <new>using namespace std;class Person{public:Person();Person(int n, const string &str);Person(const Person &n);~Person();private:int age;string *name;};Person::Person():age(0), name(NULL){cout << "Default Person" << endl;}Person::Person(int n, const string &str):age(n), name(new string(str)){cout << "Init Person" << endl;}//自定义拷贝构造函数Person::Person(const Person &n){if(n.name){name = new string(*n.name);age = n.age;}}Person::~Person(){if(name){cout << "~Person " << "name: " << *name << " age: " << age << endl;}delete name;}int main(){Person p1(10, string("SCOTT"));Person p2 = p1;return 0;}
运行结果:
Init Person
~Person name: SCOTT age: 10
~Person name: SCOTT age: 10
没有出现段错误,由此可见,上述解决方案可行。
- C++ Primer笔记9_构造函数_拷贝构造(深拷贝与浅拷贝)
- c++_拷贝构造函数/浅拷贝/深拷贝
- 【C++Primer】封装_拷贝构造函数
- C++_拷贝构造函数
- C++_拷贝构造函数
- 拷贝构造函数 深拷贝 浅拷贝
- 拷贝构造函数(深拷贝,浅拷贝)
- 拷贝构造函数浅拷贝深拷贝
- 拷贝构造函数,浅拷贝,深拷贝
- 拷贝构造函数 深拷贝 浅拷贝
- 拷贝构造函数----深拷贝、浅拷贝
- 拷贝构造函数与赋值函数;深拷贝,浅拷贝
- 5.c++-拷贝构造函数(深拷贝,浅拷贝)
- 拷贝构造函数(深拷贝与浅拷贝)
- C++拷贝构造函数(深拷贝与浅拷贝)详解
- Cpp--拷贝构造函数(深拷贝与浅拷贝)详解
- C++ 拷贝构造函数中浅拷贝与深拷贝
- C++拷贝构造函数与浅拷贝,深拷贝
- iOS国际化编译错误:error: read failed: The data couldn’t be read because it isn’t in the correct format.
- 如何来造就网站的权重
- Spring结合java Quartz配置实例代码详解
- 关于逻辑或的一个小小应用注意点
- 条款24:若所有参数皆需类型转换,请为此采用non-member函数
- C++ Primer笔记9_构造函数_拷贝构造(深拷贝与浅拷贝)
- GDI+ 画刷、矩阵、基本绘图函数、文字、图像
- Android开发去掉actionbar发生错误
- android 给选中的文字添加点击事件和修改audoLink 的超链接样式
- 开发Android硬件驱动程序
- swift 性能弱爆了
- 多媒体编程——摄像头录像预览
- Android布局优化
- stl map底层之红黑树插入步骤详解与代码实现