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. PairProject 总结

    结对编程人员:张迎春,赵梓皓.下面是我们一起编程的照片. 结对编程的优点: 首先,结对编程的目的是为了减少编程的错误,在编程的时候,大家一起检查错误,一起分析有没有更加合理的编写方法,所以这是结对编程 ...

  2. 作业6-COSPLAY孩子他家长

    为了我提高我女儿的数学能力,我以下我会根据我想要的功能做出相应的解决方案,为了孩子,父母也可以想的比老师周到.可怜天下父母心. 编号.          名称.                     ...

  3. Aspose for Maven 使用

    https://blog.aspose.com/2014/08/12/aspose-for-maven-aspose-cloud-maven-repository/ https://marketpla ...

  4. What is the best Java email address validation method?

    https://stackoverflow.com/questions/624581/what-is-the-best-java-email-address-validation-method htt ...

  5. .NET Framework 版本和依赖关系[微软官方文档]

    .NET Framework 版本和依赖关系 微软官方文档: https://docs.microsoft.com/zh-cn/dotnet/framework/migration-guide/ver ...

  6. modern effective C++ -- Deducint Types

    1. 理解模板类型推导 1. expr是T& template<typename T> void f(T & param); // 我们声明如下变量 int x = 27; ...

  7. flask+mako+peewee(上)

    其实关于什么用flask搭建一个后台博客啥的跟着官方文档做一遍就行了.感觉啥都有我这里就不赘述了只是记录一个笔记,因为稍微有几个地方有点坑. 目标:做了一个简易页面给电商的同事用来添加商品 首先是安装 ...

  8. PostgreSQL之Sequence序列(转)

    本文转载自:https://blog.csdn.net/omelon1/article/details/78798961 Sequence序列 Sequence是一种自动增加的数字序列,一般作为行或者 ...

  9. 在使用ADOQuery删除数据时的处理 [问题点数:100分,结帖人isdxsc]

    在使用ADOQuery删除数据时的,希望在他的事件BeforeDelete进行一些判断,符合要求的进行删除,不符合要求的终止这个删除行为,请问应该用什么语句呢?还有个比较奇怪的现象也一起请教:DBGr ...

  10. BZOJ3669[Noi2014]魔法森林——kruskal+LCT

    题目描述 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节点1,隐士则住 ...