我正在使用 MFC 中的 CPoint 类。没有明确定义的赋值运算符或复制构造函数 (AFAIK)。然而,这有效:
C点 p1(1, 2), p2; p2 = p1; // p2 现在等于 p1
我假设这是由于编译器生成的赋值运算符而自动工作的。正确的?
如果是这样,我可以确信这没有做任何意想不到的事情吗?在这种情况下,CPoint 非常简单,我认为一切都很好,但总的来说,这让我有点担心。这样做是否更好:
p2.SetPoint(p1.x, p2.x);
-cr
我正在使用 MFC 中的 CPoint 类。没有明确定义的赋值运算符或复制构造函数 (AFAIK)。然而,这有效:
C点 p1(1, 2), p2; p2 = p1; // p2 现在等于 p1
我假设这是由于编译器生成的赋值运算符而自动工作的。正确的?
如果是这样,我可以确信这没有做任何意想不到的事情吗?在这种情况下,CPoint 非常简单,我认为一切都很好,但总的来说,这让我有点担心。这样做是否更好:
p2.SetPoint(p1.x, p2.x);
-cr
这是安全的——如果不打算提供赋值运算符,那么 MFC 设计者可以确保它不可用(例如,通过将其设为私有)。
IIRC 编译器将执行逐个成员的复制,因此对于像这样包含 POD 的类,您不会有问题。如果您有一个分配内存的类并且忽略覆盖 operator= 并执行深度复制,它可能会变得混乱。
FWIW 我问了一个关于编译器可以做什么和不能做什么的问题:
为什么 C++ 编译器不定义 operator== 和 operator!=?
一些答案使阅读变得有趣。
查找默认的复制构造函数:
http://www.fredosaurus.com/notes-cpp/oop-condestructors/copyconstructors.html
这不是 CPoint 的特别之处。
如果一个类是“简单的”,那么编译器生成的赋值运算符将起作用(按成员复制)。如果有一些成员需要更高级的逻辑(假设对象维护一个指向它所期望的私有缓冲区的内部指针),那么编译器生成的赋值运算符就会出现问题。CPoint
只存储一个点的 x 和 y 坐标,所以你不应该遇到问题。
我不知道 MFC,但我可以猜到(或者):
内置的复制赋值操作符只是使用它们的复制赋值操作符依次复制每个成员。我假设 CPoint 不查看其文档是安全的(原因:如果不是,他们当然会提供自己的实现)。该点类应该只有两个成员(x 和 y),它们只是浮点数(或 int,取决于它的用途)。
有人说这是一个“浅拷贝”,因为只复制了成员的值。如果您有指针成员,则会复制指针值,而不是指针指向的对象。
对于像 CPoint 这样的简单数据对象(您可以从 Visual Studio 安装中包含的 MFC 源代码中看到,它只是一个带有一些便利功能的 Win32 POINT 结构),使用编译器生成的赋值运算符没有任何问题。
但如前所述,默认赋值运算符是浅拷贝,如果结构包含指针(或包含包含指针但未定义赋值运算符的结构),则会给您带来麻烦。由于 CPoint 不符合该描述,因此它是安全的。
是的。如果你operator=
在一个类上没有定义任何方法,编译器会为你生成一个方法,它只是简单地对类中的字段进行按位复制。我记得,CPoint
is just {int x; int y}
,所以按位复制就可以了。