C++ Primer笔记9_构造函数_拷贝构造(深拷贝与浅拷贝)
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++ Primer | 15】构造函数与拷贝控制
合成拷贝控制与继承 #include <iostream> using namespace std; class Base { public: Base() { cout << ...
- C++ 构造函数_拷贝构造函数
拷贝构造函数
- C++基础-4-封装(构造函数与析构函数,深拷贝与浅拷贝,静态成员,this,友元,const修饰成员函数)
4. 封装 4.1.1 封装的意义 1 #include<iostream> 2 #include<string> 3 using namespace std; 4 5 con ...
- 借jQuery对象拷贝学习深拷贝与浅拷贝
jQuery.extend([deep], target, object1, [objectN]) 即用一个或多个其他对象来扩展一个对象,返回被扩展的对象. deep:如果设为true,则递归合并. ...
- 构造函数,拷贝构造和赋值运算符调用时机,explicit,
#include<iostream> #include <stdio.h> using namespace std; class test{ int mvalue; publi ...
- C++构造函数实例——拷贝构造,赋值
#define _CRT_SECURE_NO_WARNINGS //windows系统 #include <iostream> #include <cstdlib> #incl ...
- C++ Primer笔记1_转义字符_标准库类型string_标准库类型vector
1.转义字符 一般有两种方式: \x后紧跟1个或多个十六进制数字.或\后紧跟1.2.3个八进制数字,当中数字部分是字符相应的数值. #include <iostream> using na ...
- [terry笔记]11gR2_DataGuard搭建_拷贝数据文件
11gR2搭建dataguard环境: 自己做的实验,后续按照rman模式搭建.主备切换.模式调整等实验会陆续发上来. primary: OS:oel 6.4 database:11.2.0.4.0 ...
- python的拷贝(深拷贝和浅拷贝)
今天看了几篇关于python拷贝的博文,感觉不太清楚,所以我就自己做实验试一下,特此记录. 拷贝是针对组合对象说的,比如列表,类等,而数字,字符串这样的变量是没有拷贝这一说的. 实现拷贝有: 1.工厂 ...
随机推荐
- GridBagLayout练习
摘自http://blog.csdn.net/qq_18989901/article/details/52403737 GridBagLayout的用法 GridBagLayout是面板设计中最复杂 ...
- 使用Comparable接口的小例子
代码: public class Student implements Comparable<Student> { private int id; private String name; ...
- 格而知之4:寻找EXC_BAD_ACCESS
EXC_BAD_ACCESS算是一个比较常见的错误,大部分情况下,它出现在某个对象还未初始化或已被释放后,还去试图访问这个对象的时候,即是在出现悬挂指针的时候(当然也有非悬挂指针导致的EXC_BAD_ ...
- vector的内存分配与释放
1. vector内存分配 <Effective STL>中"条款14":使用reserve来避免不必要的重新分配 关于STL容器,最神奇的事情之一是只要不超过它们的最 ...
- Riak VClock
Riak VClock 关于向量时钟的概念.在这里就多讲了,大家能够參照一下Dynamo的论文了解一下,向量时钟在分布式主要用于解决一致性性问题.能够和CRDTs一起看. 以下的源码是參照riak中的 ...
- DAT文件怎样打开
DAT文件类型主要是"数据"文件.能够是不论什么内容,比方:文字,图形,视频或一般的二进制数据,它并没有统一详细的结构.所以您不能理解它也相应一个用来打开它的应用程序.比方你看到一 ...
- 提交App,请求Apple加急审核
转载自:http://blog.csdn.net/showhilllee/article/details/19541493 提交完毕后进入加急审核页面. 链接:https://developer.ap ...
- kaggle之电影评论文本情感分类
电影文本情感分类 Github地址 Kaggle地址 这个任务主要是对电影评论文本进行情感分类,主要分为正面评论和负面评论,所以是一个二分类问题,二分类模型我们可以选取一些常见的模型比如贝叶斯.逻辑回 ...
- mysql命令学习笔记(1):show table status like 'user';显示表的相关信息
show table status like 'user';显示表的相关信息 +------------+--------+---------+------------+------+-------- ...
- Android studio教程:[4]真机测试
有了Android studio这么好用的软件,自然要有一部不错的安卓手机,然后在真机上测试自己的程序,那样才能更好的发现程序中存在的问题,毕竟模拟器不是真正的手机嘛. 工具/原料 Android s ...