c++ - 常量类成员、赋值运算符和 QList

标签 c++ qt assignment-operator qlist class-constants

如果我说的对请采纳并告诉我是否有更好的解决方案:

我了解具有常量成员的对象,如 int const width; 不能由编译器隐式创建的合成赋值运算符处理。但是 QList(我想 std::list 也是)需要一个有效的赋值运算符。因此,当我想使用具有常量成员和 QList 的对象时,我有三种可能性:

  1. 不要使用常量成员。 (不是解决方案)
  2. 实现我自己的赋值运算符。
  3. 使用其他一些不需要赋值的容器 运营商

这是正确的吗?还有其他优雅的解决方案吗?

另外我想知道我是否可以:

  • (4) 强制编译器创建一个处理常量成员的赋值运算符! (我不明白为什么这是一个这么大的问题。为什么运算符不够智能,无法在内部使用初始化列表?还是我遗漏了什么?)
  • (5) 告诉QList我永远不会在列表中使用赋值操作。

编辑:我从来没有自己分配这个类的对象。它们仅由复制构造函数或重载构造函数创建。所以赋值运算符只有容器需要,我自己不需要。

EDIT2:这是我创建的赋值运算符。我不确定它是否正确。 Cell 有一个两个参数的构造函数。这些参数使用初始化列表设置两个常量成员。但是该对象还包含其他变量(非 const)成员。

Cell& Cell::operator=(Cell const& other)
{
 if (this != &other) {
  Cell* newCell = new Cell(other.column(), other.row());
  return *newCell;
 }
 return *this;
}

EDIT3:我发现这个线程有几乎相同的问题:C++: STL troubles with const class members所有答案结合在一起回答了我的问题。

最佳答案

您可能是 C++ 的新手,并期望它的行为类似于 Python、Java 或 C#。

将不可变的 Java 对象放入集合中是很常见的。这是可行的,因为在 Java 中,您并没有真正将 Java 对象 放入集合中,而只是将引用 Java 对象的 Java 引用 放入集合中。更准确的说,一个集合内部由Java引用变量组成,赋值给这些Java引用变量根本不会影响引用的Java对象。他们甚至没有注意到。

我故意说“Java对象”、“Java引用”和“Java变量”,因为“对象”、“引用”和“变量”这三个术语在C++中有着完全不同的含义。如果你想要可变的 T 变量,你想要可变的 T 对象,因为变量和对象在 C++ 中基本上是一样的:

A variable is introduced by the declaration of an object. The variable's name denotes the object.

在 C++ 中,变量不包含对象——它们对象。给变量赋值意味着改变对象(通过调用成员函数operator=)。没有其他办法了。如果你有一个不可变对象(immutable对象),那么赋值 a = b 不能 可能在不显式破坏类型系统的情况下工作,如果你这样做,那么你实际上是在欺骗你的客户关于对象是不可变的。作出 promise 然后故意违背它是毫无意义的,不是吗?

当然,您可以简单地模拟 Java 方式:使用一组指向不可变对象(immutable对象)的指针。这是否是一个有效的解决方案取决于您的对象真正代表什么。但仅仅因为这在 Java 中运行良好并不意味着它在 C++ 中运行良好。 在 C++ 中没有不可变值对象模式这样的东西。这在 Java 中是个好主意,在 C++ 中是个糟糕的主意。

顺便说一句,您的赋值运算符完全不符合惯用语并且会泄漏内存。如果你认真学习 C++,你应该阅读 one of these books .

关于c++ - 常量类成员、赋值运算符和 QList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4288190/

相关文章:

c++ - 使用 for_each 打印复杂对象

c++ - 复制构造函数类

c++ - 使用 QSqlTableModel 获取重复记录

c++ - Qt - 设置.o文件的输出路径

c++ - 在 Win7 X64 上使用 Qt Access MS Access 数据库

c++ - 模板类复制内部类问题中的模板赋值运算符

C++ OutputIterator 后递增要求

c++ - 将只移动结构绑定(bind)到函数

javascript - 赋值运算符、映射和 promise 。该代码有什么问题? Javascript

c++ - 重载运算符 = 在 C++ 中有两个参数