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.工厂 ...
随机推荐
- 二分图带权最大独立集 网络流解决 hdu 1569
方格取数(2) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- 很少人知道的office专用卸载工具
Microsoft Office是微软公司开发的一套基于 Windows 操作系统的办公软件套装.常用组件有 Word.Excel.Powerpoint等.当我们不需要再用了或者想安装旧版本的话,首先 ...
- 理解java中【同步】和【死锁】
一.理解同步 要想解决资源共享的同步操作问题,可以使用两种方法: 使用同步代码块 之前学习过程中,代码块分为四种: l 普通代码块:是直接定义在方法之中的: l 构造块 ...
- 加载本地html遇到的问题
之前要做一个Demo,需要用UIWebView来加载网页,前端的同事把资源包给我,里面包含html,css,JavaScript,图片等文件.我想当然的把文件夹拷到工程中,然后用以下方法加载: NSU ...
- 安装Oracle11后在SQL Developer启动时提示:enter the full pathname for the java.exe
1) Open the file ..\sqldeveloper\sqldeveloper\bin\sqldeveloper.conf and add the following line to se ...
- 项目总结之MIT (一)
打开Plan才知道,原来这个项目伴随了我整个八月,做项目的时间果然特别快~~ 首先把之前出现但是只知其然但是不知其所以然的知识点总结一下 一.使用母版页 二.Ajax 控件 & Custome ...
- font-face 使用
<style type="text/css"> @font-face{ font-family:'Aaargh'; src:url(fonts/Aaargh/Aaarg ...
- google visit
http://emuch.net/bbs/viewthread.php?tid=7630684&fpage=3&target=blank 内Facebook,twitter,dropb ...
- MyBatis 注解
注解 目标 相对应的 XML 描述 @CacheNamespace 类 <cache> 为给定的命名空间 (比如类) 配置缓存. 属性:implemetation,eviction, fl ...
- Java编程思想——类型信息(RTTI)
一.概念 编译时已知的到所有的类型:就是在写代码阶段就确定是这个类型了,当运行程序的时候,类型是不可改变的 举例:List<String> str = new ArrayList(); ...