C++进阶--拥有资源句柄的类(浅拷贝,深拷贝,虚构造函数)
// Person通过指针拥有string
class Person {
public:
Person(string name) { pName_ = new string(name); }
~Person() { delete pName_; }
void printName() { cout << *pName_; }
private:
string* pName_;
};
int main() {
vector<Person> persons;
persons.push_back(Person("George"));
persons.front().printName(); //这里会崩
cout << "Goodbye" << endl;
}
//persons.push_back(Person("George")); 事实上该行代码可以分解成以下步骤
// 1. "George" 被构造
// 2. "George"的一个副本保存到(浅拷贝)
// 3. "George"被销毁
// Solution 1: 定义拷贝构造和拷贝赋值实现深拷贝
Person(const Person& rhs) {
pName_ = new string(*(rhs.pName()));
}
Person& operator=(const Person& rhs);
string* pName() const { return pName_; }
// Solution 2: 禁用拷贝构造和拷贝赋值
// 对C++ 11,使用=delete
// for C++ 03, 声明但不定义
Person(const Person& rhs);
Person& operator=(const Person& rhs);
// 如果禁用之后仍然需要拷贝,使用clone()
// 显式的拷贝
Person* clone() {
return (new Person(*(pName_)));
}
// 更推荐方法2:
// 1. 因为拷贝构造和拷贝赋值经常并不需要
// 2. 使拷贝显式,隐式拷贝容易出现bug
// 3. clone可以利用多态实现虚构造函数,自动根据指针所指对象的类型拷贝基类或者派生类对象
class Dog {
public:
virtual Dog* clone() { return (new Dog(*this)); } //co-variant return type 允许覆写函数具有不同的返回类型,只要返回类型由基类的返回类型派生得到
};
class Yellowdog : public Dog {
virtual Yellowdog* clone() { return (new Yellowdog(*this)); }
};
void foo(Dog* d) { // d 是Yellowdog
//Dog* c = new Dog(*d); // c 是Dog,不是我们想要的
Dog* c = d->clone(); // c是Yellowdog
//...
//
}
int main() {
Yellowdog d;
foo(&d);
}
// C++ 11 的方法:
// shared_ptr<string> pName_;
// 大多数情况下用unique_ptr也可以, 但是跟STL container一起使用时必须使用shared_ptr,
// 因为STL容易要求元素时可拷贝的
C++进阶--拥有资源句柄的类(浅拷贝,深拷贝,虚构造函数)的更多相关文章
- C++_进阶之函数模板_类模板
C++_进阶之函数模板_类模板 第一部分 前言 c++提供了函数模板(function template.)所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体制定,用一个虚拟的类型来 ...
- 关于MFC资源句柄、ID和对象
一.资源.句柄和ID 资源: MFC中的资源,如菜单.对话框.图标.工具条.对话框等,是windows创建的,并占用堆内存.windows在创建这些资源时候会给每个资源分配一个句柄,用来标记这些资源, ...
- 【python进阶】详解元类及其应用2
前言 在上一篇文章[python进阶]详解元类及其应用1中,我们提到了关于元类的一些前置知识,介绍了类对象,动态创建类,使用type创建类,这一节我们将继续接着上文来讲~~~ 5.使⽤type创建带有 ...
- C++进阶--派生类的析构(虚析构函数,shared_ptr)
//############################################################################ /* 在多态虚基类中声明一个虚析构函数 * ...
- Scala进阶之路-Scala特征类与unapply反向抽取
Scala进阶之路-Scala特征类与unapply反向抽取 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Scala特征类分析 1>.Unit 答:用于定义返回值类型, ...
- C++ 类的深拷贝和浅拷贝完美解决
//类的深拷贝和浅拷贝 #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; class Poin ...
- js进阶 10-7 简单的伪类选择器可以干什么
js进阶 10-7 简单的伪类选择器可以干什么 一.总结 一句话总结:伪类选择器是冒号. 1.学而不用,有什么用? 多用啊,在项目中多用 2.简单的伪类选择器可以干什么? 除某元素以外,某元素的一切索 ...
- CPP_类默认函数:构造函数,拷贝构造函数,赋值函数和析构函数
类默认函数:构造函数,拷贝构造函数,赋值函数和析构函数 // person.h #ifndef _PERSON_H_ #define _PERSON_H_ class Person{ public : ...
- C++类中函数(构造函数、析构函数、拷贝构造函数、赋值构造函数)
[1]为什么空类可以创建对象呢? 示例代码如下: #include <iostream> using namespace std; class Empty { }; void main() ...
随机推荐
- TLS编程
最近测试广州电信的电话会议平台,该平台接入采用HTTPS协议,于是有了本文.09年培训时写过一个简单的TLS C/S结构交互,采用openssl的ssl相关接口,但与生产相去胜远.本文采用openss ...
- ps使用图层合并切图
1.新建图层 2.合并要切的图的图层和新建的空白图层 3用正方形工具圈出来要切得图 4.ctrl+c复制,ctrl+n新建,ctrl+v复制过去 5,切图
- 20155208实验三 敏捷开发与XP实践
20155208实验三 敏捷开发与XP实践 一.实验内容 (1)在IDEA中使用工具(Code->Reformate Code)把下面代码重新格式化,再研究一下Code菜单,找出一项让自己感觉最 ...
- windows apache "The requested operation has failed" 启动失败
找到失败原因,进入cmd(win+r快捷键,输入cmd)命令行下 进入到你的apache bin目录下: 每个人错误可能不同,根据自己问题去相应改
- 实验吧—隐写术——WP之 男神一般都很低调很低调的!!
首先我们打开解题连接~ 是直接给我们下载了一个压缩文件,解压后得到: 确实是很帅的小哥哥呢,呵呵...... 分析题目提示,“获取隐藏在图片中的flag”,嗯~这句很重要,他决定了我们要先用那种工具 ...
- js动态加载数据并合并单元格
js动态加载数据合并单元格, 代码如下所示,可复制直接运行: <!DOCTYPE HTML> <html lang="en-US"> <head> ...
- 【shell编程】之基础知识-流程控制
和Java.PHP等语言不一样,sh的流程控制不可为空,如(以下为PHP流程控制写法): <?php if (isset($_GET["q"])) { search(q); ...
- LG4238 【【模板】多项式求逆】
前言 学习了Great_Influence的递推实现,我给大家说一下多项式求逆严格的边界条件,因为我发现改动一些很小的边界条件都会使程序出错.怎么办,背代码吗?背代码是不可能,这辈子都不会背代码的.理 ...
- showdoc 开源在线api&&技术文档管理工具
showdoc 是一个很不错的api 以及技术文档管理工具 环境准备 doker-copose 文件 version: "3" services: doc: image: regi ...
- SAS常用函数
SAS常用函数 一.数学函数 ABS(x) 求x的绝对值. MAX(x1,x2,…,xn) 求所有自变量中的最大一个. MIN(x1,x2,…,xn) 求所有自变量中的最小一个. MOD(x,y) ...