第12.8 / 7节中的标准说:
如果类定义未明确声明一个副本构造函数,则将隐式声明一个副本构造函数。如果类定义声明了move构造函数或move赋值运算符,则隐式声明的copy构造函数将定义为delete;否则,将其定义为默认值(8.4)。如果 该类具有用户声明的副本分配运算符或用户声明的 析构函数,则不建议使用后一种情况。因此,对于类定义
struct X { X(const X&, int); };
复制构造函数被隐式声明。如果用户声明的构造函数以后定义为
X::X(const X& x, int i =0) { /∗ ... ∗/ }
我不能理解的是,如果类具有用户声明的副本分配运算符或用户声明的析构函数,则不建议使用后一种情况。在示例中,标准既不提供用户声明的副本分配运算符,也不提供析构函数。如果我们声明一个析构函数或一个拷贝赋值运算符,将会发生什么?我尝试这样做,如下所示:
struct A
{
~A(){ };
};
A::A(const A&){ }; //error
int main(){ }
但是在示例中,我们仍然具有隐式声明的副本构造函数。该规则实际意味着什么?
我以为如果我们写以下内容:
struct A
{
A(){ };
A(const A&&){ };
~A(){ };
};
A a;
A t = a; //error: call to implicitly-deleted copy constructor of 'A'
int main()
{
}
复制构造函数不会明确删除。但是事实并非如此。
此弃用基本上包含了“三(五)规则”。如果提供了用户声明的副本分配运算符或析构函数,则不赞成将副本构造函数定义为默认(而不是删除)的事实。那应该防止您将来依赖于这样一个隐式声明的副本构造函数。
在该示例中,标准既不提供拷贝分配也没有提供析构函数,而用户均未对其进行销毁。
该示例与弃用无关。
我尝试这样做,如下所示:[…]但是在示例中,我们仍然具有隐式声明的副本构造函数。
您不能定义一个隐式声明的副本构造函数-因为它已经由by定义= default
(没有双关语)。您必须先自己声明。
我以为如果我们写以下内容:[…]复制构造函数将不会被明确删除。但这不是真的。
您引用了以下规则:如果声明了移动构造函数,则该规则明确指定将复制构造函数隐式定义为已删除:
如果类定义声明了move构造函数或move赋值运算符,则隐式声明的copy构造函数将定义为delete;
显然,
A(const A&&){ }
是根据[class.copy] / 3的move构造函数。如果删除了此move构造函数,则示例将编译,尽管它使用了已弃用的功能。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句