安全使用编译器生成的赋值运算符?

问题描述 投票:3回答:7

我正在使用MFC的CPoint类。没有明确定义的赋值运算符或复制构造函数(AFAIK)。然而,这有效:

CPoint p1(1, 2), p2;
p2 = p1; // p2 now is equal to p1

我假设这是由于编译器生成的赋值运算符而自动运行。正确?

如果是这样,我是否可以确信这没有做任何意想不到的事情?在这种情况下,CPoint是如此简单,我认为一切都很好,但总的来说这是让我担心的事情。这是更好的形式:

p2.SetPoint(p1.x, p2.x);

-cr

c++ mfc variable-assignment
7个回答
4
投票

这是安全的 - 如果不打算提供赋值运算符,那么MFC设计者可以确保它不可用(例如将其设为私有)。

IIRC编译器将执行逐个成员的副本,因此对于包含这样的POD的类,您将不会遇到问题。如果你有一个分配内存的类并且忽略覆盖operator =并执行深拷贝,那么它可能会变得混乱。

FWIW我问了一个关于编译器可以做什么和不能做什么的问题:

Why don't C++ compilers define operator== and operator!=?

一些答案有助于阅读。


3
投票

查找默认的复制构造函数:

http://www.fredosaurus.com/notes-cpp/oop-condestructors/copyconstructors.html

关于CPoint这不是一件特别的事。


1
投票

如果一个类是“简单的”,那么编译器生成的赋值运算符将起作用(成员复制)。如果有一些成员需要更高级的逻辑(假设对象维护了一个指向它所期望的私有缓冲区的内部指针),那么编译器生成的赋值运算符就会出现问题。 CPoint只存储一个点的x和y坐标,所以你不应该遇到问题。


0
投票

对于像CPoint这样的简单数据对象(您可以从Visual Studio安装中包含的MFC源中看到它只是一个Win32 POINT结构,其中添加了一些便利功能),使用编译器生成的赋值运算符没有任何问题。

但是正如已经提到的,默认赋值运算符是一个浅表副本,如果结构包含指针(或者包含不包含赋值运算符的指针的结构),则会让您遇到麻烦。由于CPoint不符合该描述,因此它是安全的。


0
投票

内置的复制赋值运算符只是使用它们的复制赋值运算符依次复制每个成员。我认为没有查看其文档对CPoint是安全的(原因:如果不是,他们会提供自己的实现,当然)。那个点类应该只有两个成员(x和y),那些只是浮点数(或int取决于它的用途)。

有人说这是一个“浅层副本”,因为只复制了成员的值。如果有指针成员,则复制指针值,而不是指针所指向的对象。


0
投票

我不知道MFC,但我可以猜到(或者):

  • CPoint有一个已定义的赋值运算符(因此不是编译器生成的),或者
  • 编译器生成的赋值运算符在成员进行堆栈分配时起作用,因此它会进行成员复制。

0
投票

是。如果在类上没有定义operator=方法,编译器会为您生成一个只是对类中的字段进行按位复制的方法。我记得,CPoint只是{int x; int y},所以按位复制很好。

© www.soinside.com 2019 - 2024. All rights reserved.