拷贝控制和资源管理

• 类的行为像一个值。意味着它应该有自己的状态,当我们拷贝一个像值得对象时,副本和原对象是完全独立的,改变副本不会对原对象有任何影响。

• 行为像指针的类则共享状态。当我们拷贝一个这种类的对象时,副本和原对象使用相同的底层数据,改变副本也会改变原对象。

13.2节练习

 #include<iostream>
#include<string>
using namespace std; class HasPtr {
public:
HasPtr(const string &s = string()): ps(new string(s)), i() {}
HasPtr(const HasPtr &rhs): ps(new string(*rhs.ps)), i(rhs.i) {} HasPtr &operator=(const HasPtr &rhs);
HasPtr &operator=(const string &rhs);
string &operator*(); ~HasPtr() { delete ps; }
private:
string *ps;
int i;
}; HasPtr &HasPtr::operator=(const HasPtr &rhs)
{
auto newp = new string(*rhs.ps);
delete ps;
ps = newp;
i = rhs.i;
return *this;
} HasPtr &HasPtr::operator=(const string &rhs)
{
*ps = rhs;
return *this;
} string& HasPtr::operator*()
{
return *ps;
} int main()
{
HasPtr h("hi mom!");
HasPtr h2(h);
HasPtr h3(h);
h2 = "hi dad!";
h3 = "hi, son!";
cout << "h: " << *h << endl;
cout << "h2: " << *h2 << endl;
cout << "h3: " << *h3 << endl;
return ;
}

运行结果:

行为像值的类

 #include<iostream>
#include<string>
using namespace std; class HasPtr {
public:
HasPtr(const string &s = string()): ps(new string(s)), i() {}
HasPtr(const HasPtr &rhs): ps(new string(*rhs.ps)), i(rhs.i) {} HasPtr& operator=(const HasPtr &rhs);
~HasPtr() { delete ps; }
private:
string *ps;
int i;
}; HasPtr& HasPtr::operator=(const HasPtr &rhs)
{
auto newp = new string(*rhs.ps);
delete ps;
ps = newp;
return *this;
}

定义行为像指针的类

 #include<iostream>
#include<string>
using namespace std; class HasPtr {
public:
HasPtr(const string &s = string()): ps(new string(s)), i(), use(new size_t()) {}
HasPtr(const HasPtr &rhs): ps(rhs.ps), i(rhs.i), use(rhs.use) { ++*use; } HasPtr &operator=(const HasPtr &rhs);
~HasPtr(); private:
string * ps;
int i;
size_t *use; //用来记录有多少个对象共享*ps的成员
}; HasPtr &HasPtr::operator=(const HasPtr &rhs)
{
++*rhs.use;
if (--*use == )
{
delete ps;
delete use;
}
ps = rhs.ps;
i = rhs.i;
use = rhs.use;
return *this;
} HasPtr::~HasPtr()
{
if (--*use == )
{
delete ps;
delete use;
}
}

【C++ Primer 第13章】2. 拷贝控制和资源管理的更多相关文章

  1. [C++ Primer] : 第13章: 拷贝控制

    拷贝, 赋值与销毁 当定义一个类时, 我们显示地或隐式地指定在此类型的对象拷贝, 移动, 赋值和销毁时做什么. 一个类通过定义5种特殊的成员函数来控制这些操作, 包括: 拷贝构造函数, 拷贝赋值运算符 ...

  2. C++ 拷贝控制和资源管理,智能指针的简单实现

    C++ 关于拷贝控制和资源管理部分的笔记,并且介绍了部分C++ 智能指针的概念,然后实现了一个基于引用计数的智能指针.关于C++智能指针部分,后面会有专门的研究. 通常,管理类外资源的类必须定义拷贝控 ...

  3. [C++]类的设计(2)——拷贝控制(拷贝控制和资源管理)

      1.类的行为分类:看起来像一个值:看起来想一个指针.     1)类的行为像一个值,意味着他应该有自己的状态.当我们拷贝一个像值的对象时,副本和原对象是完全独立的.改变副本不会对原有对象有任何影响 ...

  4. 【C++ Primer 第13章】1. 拷贝控制、赋值和销毁

    拷贝控制.赋值和销毁 如果一个构造函数的第一个参数是自身类的引用,且额外的参数都有默认值,则此构造函数是拷贝控制函数(拷贝构造函数不应该是explicit的). 如果我们没有为一个类定义拷贝构造函数, ...

  5. C++ Primer : 第十三章 : 拷贝控制之拷贝控制和资源管理

    定义行为像值的类 行为像值的类,例如标准库容器和std::string这样的类一样,类似这样的类我们可以简单的实现一个这样的类HasPtr. 在实现之前,我们需要: 定义一个拷贝构造函数,完成stri ...

  6. 【C++ Primer | 15】构造函数与拷贝控制

    合成拷贝控制与继承 #include <iostream> using namespace std; class Base { public: Base() { cout << ...

  7. 【C++ Primer 第13章】3. 交换操作

    交换操作 class HasPtr { friend void swap(HasPtr &rhs, HasPtr &yhs); //其他成员定义 }; void swap(HasPtr ...

  8. 【C++ Primer 第13章】6.对象移动

    右值引用 左值和右值 (1)两者区别: ①左值:能对表达式取地址.或具名对象/变量.一般指表达式结束后依然存在的持久对象. ②右值:不能对表达式取地址,或匿名对象.一般指表达式结束就不再存在的临时对象 ...

  9. 【C++ Primer 第13章】5. 动态内存管理类

    StrVec类的设计 [题目描述]:我们将实现标准库vector类的一个简化版本,我们所做的一个简化是不使用模板,我们类只用于string,因此,它被命名为StrVec. #include<io ...

随机推荐

  1. CF1100E Andrew and Taxi

    题目地址:CF1100E Andrew and Taxi 二分,每次取到一个 \(mid\) ,只保留长度 \(>mid\) 的边 dfs判环,若有环,说明 \(ans>mid\) ,否则 ...

  2. 20165325 2017-2018-2 《Java程序设计》结对编程_第一周:四则运算

    一.码云链接 项目名称FAO 码云链接 二.需求分析 实现一个命令行程序: 自动生成小学四则运算题目(加.减.乘.除) 支持整数 支持多运算符(比如生成包含100个运算符的题目) 支持真分数 统计正确 ...

  3. ASP.NET Core中使用Autofac

    ⒈添加相关依赖 Install-Package Autofac ⒉扫描项目接口实现类 using Autofac; using System; using System.Collections.Gen ...

  4. 1.Python_字符串_常用办法总结

    明确:对字符串的操作方法都不会改变原来字符串的值. 1.去掉空格和特殊符号 name.strip() 去掉空格和换行符 name.strip("xx") 去掉某个字符串 name. ...

  5. 64位程序,利用ADO连接Oracle数据库

        刚好手头项目解决了ADO连接Oracle数据库的问题,记录下来,防止忘记. 项目情况:用32位环境完成算法动态库,结果后来需要升级到64位环境,由64位的软件来调用,则在64位设置下生成算法动 ...

  6. 【转】Linux中profile、bashrc、bash_profile之间的区别和联系

    /etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登陆时,该文件被执行.并从/etc/profile.d目录的配置文件中搜集shell的设置. 英文描述为: # /etc/pr ...

  7. 【转】vector中erase()的使用注意事项

    vector::erase():从指定容器删除指定位置的元素或某段范围内的元素 vector::erase()方法有两种重载形式 如下: iterator erase(   iterator _Whe ...

  8. CTex+WinEdt10.2安装详细教程与破解

    原文地址:https://www.cnblogs.com/xiachongkun/p/8176390.html Latex作为目前最好用的文档编排工具,以前只是简单会一点,现在也已经忘得差不多了.因为 ...

  9. struts2框架学习之第二天

    day02 下面是在每个Action之前都会执行的拦截器,这段代码来自与struts-default.xml文件. <interceptor-stack name="defaultSt ...

  10. nginx 负载 问题

    1 如果使用ip_hash,nginx必须为最前端负载均衡,如果大网环境部署,基本无法实现,内网还可以使用 2 如果不使用ip_hash,则要考虑session问题,可以使用memcached与tom ...