如果我说的对请采纳并告诉我是否有更好的解决方案:
我了解具有常量成员的对象,如 int const width;
不能由编译器隐式创建的合成赋值运算符处理。但是 QList(我想 std::list 也是)需要一个有效的赋值运算符。因此,当我想使用具有常量成员和 QList 的对象时,我有三种可能性:
- 不要使用常量成员。 (不是解决方案)
- 实现我自己的赋值运算符。
- 使用其他一些不需要赋值的容器 运营商
这是正确的吗?还有其他优雅的解决方案吗?
另外我想知道我是否可以:
- (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/