1.确保当对象自我赋值时operator=有良好的行为,其中的技术包括 "来源对象" 和 "目标对象" 的地址,精心周到的语句顺序,以及“ copy and swap ” 技术

2.确定任何函数执行操作一个以上对象时,而其中多个对象是同一个对象时,其行为任然正确

 #include <iostream>

 //1.0
class CopySwap1_0
{
private:
int *value;
public:
CopySwap1_0() : value(new int())
{} ~CopySwap1_0()
{ delete value; }; //不符合 "C++异常安全" 1.没有考虑自赋值情况. 2.new抛出异常的话,原数据销毁
CopySwap1_0 &operator=(const CopySwap1_0 &rhs)
{
delete value;
value = new int(*rhs.value);
return *this; } }; //2.0
class CopySwap2_0
{
private:
int *value;
public:
CopySwap2_0() : value(new int())
{} ~CopySwap2_0()
{ delete value; }; //保证异常安全,和自赋值情况,但执行效率可以提高
CopySwap2_0 &operator=(const CopySwap2_0 &rhs)
{
if (this == &rhs) return *this; int *temp = value;
value = new int(*rhs.value);
delete temp;
return *this;
} }; //3.0
class CopySwap3_0
{
friend void swap(CopySwap3_0& lhs,CopySwap3_0& rhs);
private:
int *value;
public:
CopySwap3_0() : value(new int())
{} ~CopySwap3_0()
{ delete value; }; CopySwap3_0(const CopySwap3_0& rhs)
{
value=new int(*rhs.value);
//other work
} //这样做我们会失去一个重要的优化机会
//通常,我们最好遵循比较有用的规则是:不要拷贝函数参数。你应该按值传递参数,让编译器来完成拷贝工作。 // CopySwap3_0 &operator=(const CopySwap3_0 &rhs)
// {
// CopySwap3_0 lhs(rhs);
// std::swap(*this, lhs);
// return *this;
//
// } // 这种管理资源的方式解决了代码冗余的问题,我们可以用拷贝构造函数完成拷贝功能,而不用按位拷贝。拷贝功能完成后,我们就可以准备交换了。
// 注意到,上面一旦进入函数体,所有新数据都已经被分配、拷贝,可以使用了。这就提供了强烈的异常安全保证:如果拷贝失败,我们不会进入到函数体内,
// 那么this指针所指向的内容也不会被改变。(在前面我们为了实施强烈保证所做的事情,现在编译器为我们做了)。
// swap函数时non-throwing的。我们把旧数据和新数据交换,安全地改变我们的状态,旧数据被放进了临时对象里。这样当函数退出时候,旧数据被自动释放。
// 因为copy-and-swap没有代码冗余,我们不会在这个而操作符里面引入bug。我们也避免了自我赋值检测。 CopySwap3_0 &operator=(CopySwap3_0 rhs)
{
swap(*this, rhs);
return *this; } }; void swap(CopySwap3_0& lhs,CopySwap3_0& rhs)
{
//using声明现在当前作用域寻找swap,没有则使用std::swap
using std::swap;
swap(lhs.value,rhs.value);
//其他指针/值操作
} int main(int argc, char **argv)
{
CopySwap3_0 A, B;
A = B;
return ;
}

Toal:一般具有管理资源分配的类使用copy and swap,效益是最好的,copy and swap 使用一次拷贝构造和析构操作换取一次拷贝赋值操作(往往拷贝赋值操作也是执行析构和拷贝操作),对于数据变量结点少的情况copy and swap是最好的,也防止自赋值和异常问题,对于资源分配的类最好实现自己的swap函数,防止循环调用赋值运算符- -;

NO.10: 在operator=中处理 "自我赋值"的更多相关文章

  1. 读书笔记 effective c++ Item 11 在operator=中处理自我赋值

    1.自我赋值是如何发生的 当一个对象委派给自己的时候,自我赋值就会发生: class Widget { ... }; Widget w; ... w = w; // assignment to sel ...

  2. 条款11:在operator=中处理“自我赋值”

    什么是自我赋值,就是 v = v 这种类型的语句,也许很多人都会说鄙视这种写法,但是如下的写法会不会出现呢? 比如:a[i] = a[j];      // 不巧的是i可能和j相等 *px = *py ...

  3. 【11】在operator=中处理“自我赋值”

    1.自我赋值,看起来愚蠢,但是却合法.有些自我赋值一眼就可看出来.有些自我赋值是潜在的.比如:a[i] = a[j]; *px = *py; 甚至不同类型的指针,都指向同一个地址,也是自我赋值,这一类 ...

  4. Effective C++_笔记_条款11_在operator=中处理“自我赋值”

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为什么会出现自我赋值呢?不明显的自我赋值,是“别名”带来的结果: ...

  5. Effective C++ 条款11:在operator=中处理"自我赋值"

    "自我赋值"发生在对象被赋值给自己时: class Widget { ... }; Widget w; ... w = w; // 赋值给自己 a[i] = a[j]; // 潜在 ...

  6. Effective C++ 条款11,12 在operator= 中处理“自我赋值” || 复制对象时不要忘记每一个成分

    1.潜在的自我赋值     a[i] = a[j];     *px = *py; 当两个对象来自同一个继承体系时,他们甚至不需要声明为相同类型就可能造成别名. 现在担心的问题是:假如指向同一个对象, ...

  7. Effective C++ -----条款11: 在operator=中处理“自我赋值”

    确保当对象自我赋值时operator=有良好行为.其中技术包括比较“来源 对象”和“目标对象”的地址.精心周到的语句顺序.以及copy-and-swap. 确定任何函数如果操作一个以上的对象,而其中多 ...

  8. [Effective C++ --011]在operator=中处理“自我赋值”

    一.何谓“自我赋值”? 1.1.场合一 直接赋值 w = w; 1.2.场合二 同一数组         a[i] = a[j]: 1.3.场合三 指针         *px = *py: 1.4. ...

  9. EC读书笔记系列之6:条款11 在operator=中处理自我赋值

    记住: ★确保当对象自我赋值时operator=有良好行为.有三种方法:比较“来源对象”和“目标对象”的地址.精心周到的语句顺序.以及copy-and-swap技术 ★确定任何函数若操作一个以上对象, ...

随机推荐

  1. bootstrap面试题

    1.你能描述一下渐进增强和优雅降级之间的不同吗? 优雅降级:Web站点在所有新式浏览器中都能正常工作,如果用户使用的是老式浏览器,则代码会检查以确认它们是否能正常工作.由于IE独特的盒模型布局问题,针 ...

  2. Vuex实现原理解析

    我们在使用Vue.js开发复杂的应用时,经常会遇到多个组件共享同一个状态,亦或是多个组件会去更新同一个状态,在应用代码量较少的时候,我们可以组件间通信去维护修改数据,或者是通过事件总线来进行数据的传递 ...

  3. doc窗口 输入命令net start mysql 服务名无效

    解决方案: 1.win+R键输入cmd敲回车进入dos界面: 2.输入cd d:/mysql-5.5.25/bin敲回车,发现没变化: 3.输入d:敲回车,定位到d:\mysql-5.5.25\bin ...

  4. github更新,发布地址,燃尽图,总结

    github地址:https://github.com/Lingchaoyang 网盘发布地址:http://pan.baidu.com/s/1qXgHiyC 燃尽图: 团队得分(100分制): 杨灵 ...

  5. git学习笔记2——ProGit2

    先附上教程--<ProGit 2> 配置信息 Git 自带一个 git config 的工具来帮助设置控制 Git 外观和行为的配置变量. 这些变量存储在三个不同的位置: /etc/git ...

  6. 百度AI--自然语言处理之Java开发

    参数: public class APIConstants { //设置APPID/AK/SK public static final String APP_ID = "108***&quo ...

  7. 微信小程序开发UI组件

    第一  view和input和button组件 1.UI组件的通用属性 (1)id       唯一标识 (2)class  设置组件的样式类 (3)style 设置组件的内联样式 (4)hidden ...

  8. LinkedList 实现 Queue

    package cn.com.example; import java.util.LinkedList; /** * Created by Jack on 2017/3/8. */ public cl ...

  9. BZOJ4034[HAOI2015]树上操作——树链剖分+线段树

    题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都 ...

  10. 有源汇有上下界最小流 DInic + 各种优化 模板

    例题:loj117 : https://loj.ac/problem/117 //其实就是判断可行流后倒着求一遍最大流 #include <iostream> #include <c ...