我想在编译器通常会自动生成默认构造函数,复制构造函数和赋值运算符的条件下刷新内存。

我记得有一些规则,但我不记得了,而且无法在线找到信誉良好的资源。有人可以帮忙吗?

#1 楼

在下文中,“自动生成”是指“隐式声明为默认值,但未定义为已删除”。在某些情况下,会声明特殊成员函数,但将其定义为已删除。


如果没有用户声明的构造函数,则默认构造函数将自动生成(第12.1 / 5节)。
如果没有用户声明的move构造函数或move赋值运算符(因为C ++ 03中没有move构造函数或move赋值运算符,则复制构造函数会自动生成),这在C + +03)(§12.8/ 8)。
如果没有用户声明的Move构造函数或Move Assign运算符(§12.8/ 19),则会自动生成副本分配运算符。
析构函数是auto如果没有用户声明的析构函数(§12.4/ 4),则生成-

C ++ 11和更高版本:


move构造函数是auto如果没有用户声明的副本构造函数,副本赋值运算符或析构函数,并且所生成的move构造函数有效(第12.8 / 10节),则生成-
如果没有用户,则自动生成Move赋值运算符声明的副本c onstructor,复制赋值运算符或析构函数,以及生成的移动赋值运算符是否有效(例如(如果不需要分配常量成员)(第12.8 / 21节)。


评论


继承的析构函数是否计数?我的意思是说我有一个带有空虚析构函数的基类。是否阻止在子类中创建move构造函数?如果答案是肯定的,那么在基类中定义move构造函数会有所帮助吗?

–牛奶
2014年7月6日13:29



我认为您应该提到也许在类中包含const成员会阻止构造函数自动生成...

–不知情
14年7月31日在23:08

是否“在某些情况下已声明特殊成员函数,但将其定义为已删除”。指的是您有const或引用成员的位置,那么将无法进行移动?不,那不可能,因为将应用副本。

–towi
16-09-27在7:37



我知道在此论坛中发送超链接是受限制的。但这也是很好的文章-cplusplus.com/articles/y8hv0pDG

–bruziuz
16-10-12在0:54

请注意,按照标准,隐式默认的副本构造函数“如果类具有用户声明的副本分配运算符或用户声明的析构函数,则不建议使用”(12.8复制和移动类对象[class.copy])。

– sigy
17 Mar 29 '17在10:59



#2 楼

我发现下面的图非常有用。


从粘滞的比特开始-成为零英雄规则

评论


美丽。 “独立”指的是什么?独立于什么?

–towi
16-09-27在7:29

复制ctor /分配彼此“独立”。如果仅编写一个,则编译器将提供另一个。相反,如果您提供了一个移动ctor或一个移动分配,则编译器将不提供另一个。

– Marco M.
16-10-3在20:14

不知道复制操作背后是独立的原因是什么。历史原因可能是?还是复制不会修改其目标却移动的事实呢?

–RaGa__M
17年7月5日在7:47



@Explorer_N是的,向后兼容,是历史原因。很久以前,这是一个错误的设计选择,因此现在需要一些良好的实践,例如“三个规则”(定义所有3个或不定义:复制构造函数,复制赋值运算符和通常为析构函数),以避免难以发现错误。

–atablash
18年3月31日在18:41

据我所知,@ MarcoM。的“如果您写...”条件包括将特殊成员函数设置为= delete(明显)或= default(对我而言不太明显)的两种情况。我对吗?

– Enlico
19年5月19日在12:46

#3 楼

C ++ 17 N4659标准草案

要获得快速的交叉标准参考,请查看以下cppreference条目的“隐式声明”部分:


https://en.cppreference.com/w/cpp/language/copy_constructor
https://en.cppreference.com/w/cpp/language/move_constructor
https://en.cppreference .com / w / cpp / language / copy_assignment
https://en.cppreference.com/w/cpp/language/move_assignment

当然可以从标准中获得相同的信息。例如。在C ++ 17 N4659标准草案上:

15.8.1“复制/移动构造函数”表示复制构造函数:


6如果类定义确实
如果类定义声明了move构造函数或move赋值运算符,则隐式声明的copy
构造函数定义为已删除;否则,将其定义为默认值(11.4)。如果该类具有用户声明的副本分配运算符或用户声明的析构函数,则不建议使用后一种情况。


并且对于移动构造函数: />
8如果类X的定义未明确声明move构造函数,则当且仅当


(8.1)
— X没有用户声明的副本构造函数,
(8.2)
— X没有用户声明的副本赋值运算符,
(8.3)
— X没有用户声明的移动分配运算符,并且
(8.4)
— X没有用户声明的析构函数。



15.8.2“复制/移动赋值运算符”对复制赋值说:


2如果类定义未明确声明复制赋值运算符,
如果类定义声明了move构造函数或move赋值运算符,则隐式声明
复制分配运算符定义为已删除;否则,将其定义为默认值(11.4)。如果该类具有用户声明的副本构造函数或用户声明的析构函数,则不建议使用后一种情况。


并进行移动分配:


4如果类X的定义未明确声明移动赋值运算符,则当且仅当


( 4.1)-X没有用户声明的副本构造函数,
(4.2)-X没有用户声明的move构造函数,
(4.3)-X没有用户声明的副本赋值运算符,并且
(4.4)— X没有用户声明的析构函数。




15.4“析构函数”对析构函数表示: >

4如果类没有用户声明的析构函数,则将析构函数隐式声明为默认值(11.4)。
隐式声明的析构函数是其类的内联公共成员。