任何陷阱的副本构造函数和赋值运算符具有语义稍有不同?

请看看下面的代码,并告诉我,如果它要在将来导致问题,如果是,如何避免它们。

class Note { int id; std::string text; public: // ... some ctors here... Note(const Note& other) : id(other.id), text(other.text) {} void operator=(const Note& other) // returns void: no chaining wanted { if (&other == this) return; text = other.text; // NB: id stays the same! } ... };

总之,我想拷贝构造函数来创建一个对象完全相同的副本,包括它的(数据库)的ID字段。 在另一方面,当我给你,我只想复制的数据字段。 但我有一些担心,因为一般的副本构造函数和操作符=具有相同的语义。

ID字段被注意和它的朋友只用。 对于所有其他客户端,赋值运算符不创建一个完全相同的副本。 用例:当我想编辑一个说明,我创建一个副本使用复制构造函数,对其进行编辑,然后调用保存在其管理的注意事项笔记本类:

Note n(notebook.getNote(id)); n = editNote(n); // pass by const ref (for the case edit is canceled) notebook.saveNote(n);

当在另一方面,我想创建一个全新注意到了相同内容的现有的音符,我可以这样做:

Note n; n = notebook.getNote(id); n.setText("This is a copy"); notebook.addNote(n);

这是合理的做法? 如果没有,请指出哪些可能产生的负面后果! 多谢!

--------------解决方案-------------

如果你想语义不匹配什么的赋值操作符预期,那么就不要使用它。 相反,禁用它宣布私人operator=和一个名称清楚是怎么回事,就像定义一个函数copyDataFields

虽然这可能对您的特定情况下,我不会推荐它一般。

库如STL期望的拷贝构造函数和赋值操作符的工作“像他们应该”。 如果你违反了C ++的语法,那么你会发现你的对象是STL容器将无法正常工作。 在STL将同时调用你的拷贝构造函数和你的赋值运算符,根据不同情况,这取决于在容器上。

这是很容易得到完全糊涂了,当你的代码没有做什么,你认为它。

从技术上讲,这是可行的,技术上的工作,但我不会做这样的说法。 我看到的问题是:

  1. 你改变“自然”语义赋值运算符的已知由C ++人口。
  2. 两个双操作,拷贝构造和赋值,是因为不同的语义不一致。
  3. 该解决方案是容易出错,因为它很容易不小心调用拷贝构造函数 ,即使它看起来分配。 如果一个程序员写你的第二个用例是这样的:

    Note n = notebook.getNote(id);

    然后拷贝构造函数被调用而不是分配 ,让您得到n比预期为不同的对象。

为什么不能让你的意图只是清晰和明确:

Note& Notebook::editNote(int id);
Note Notebook::createNote(int id);

分类:C# 时间:2015-03-15 人气:0
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 1.408 (s). 10 q(s)