我定义了一个非拷贝构造函数;复制构造函数是不是仍会被隐式定义?

Posted

技术标签:

【中文标题】我定义了一个非拷贝构造函数;复制构造函数是不是仍会被隐式定义?【英文标题】:I defined a non-copy constructor; will a copy constructor still be implicitly defined?我定义了一个非拷贝构造函数;复制构造函数是否仍会被隐式定义? 【发布时间】:2012-09-16 16:08:54 【问题描述】:

是否可以为已经用户定义的构造函数的调用(隐式)默认 复制构造函数 但那不是复制构造函数

如果可能的话,假设我们为类显式定义了复制构造函数,现在可以调用(隐式)默认构造函数吗?

【问题讨论】:

***.com/questions/10854948/… 复制构造函数和构造函数不同,它们在不同的情况下调用,一个不隐藏另一个。 问题是,你为什么要这样做。通常你定义你自己的复制构造器,因为默认的还不够——那你为什么要调用它呢? 同时拥有默认和覆盖的复制构造函数是不明确的。 【参考方案1】:

首先,让我们稍微澄清一下我们的词汇。默认构造函数是 可以不带任何参数调用的构造函数。复印件 constructor 是一个可以用单个参数调用的构造函数 同类型。鉴于此,“默认复制构造函数”将是 带有类似签名的构造函数:

class MyClass

public:
    static MyClass ourDefaultInstance;
    //  default copy constructor...
    MyClass( MyClass const& other = ourDefaultInstance );
;

不知何故,我不认为这就是你的意思。我认为什么 你问的是隐式声明还是隐式定义 复制构造函数;一个复制构造函数,其声明或定义是 由编译器隐式提供。编译器将始终提供 声明,除非您提供的声明可以 被认为是一个复制构造函数。提供其他构造函数不会 防止编译器隐式声明复制构造函数。

这与默认构造函数不同——任何用户定义 构造函数将阻止编译器隐式声明 默认构造函数。这意味着如果您有用户定义的副本 构造函数,编译器不会隐式声明一个默认值 构造函数。

第二个重点是你不要调用构造函数。这 编译器在某些定义明确的上下文中调用它们:变量 主要是定义和类型转换。编译器只能调用 已声明的构造函数(包括隐含的构造函数) 声明)。因此,如果您有用户定义的构造函数(复制或 否则),并且不定义默认构造函数,编译器不能 调用构造函数,除非在它有要调用的参数的上下文中 它与。

总结一下我认为您的问题是:编译器将提供 隐式复制构造函数,即使该类有其他用户定义 构造函数,前提是这些构造函数都不能被视为副本 构造函数。如果您提供用户定义的复制构造函数,则 编译器将提供隐式声明的默认复制构造函数。

【讨论】:

@James Kanze:很好的解释,默认的复制构造函数我的意思是由编译器隐式定义。 同意。 +1。 “默认复制构造函数”是一个带有默认值的复制构造函数,很好!这就提出了一个有趣的问题:如何构造ourDefaultInstance。默认构造它是UB。我想需要一个非默认构造函数。 @DavidHammen 是的。我只展示了我所说的最基本的一点,但是任何时候你声明一个复制构造函数,你也必须声明其他构造函数,否则你将永远无法构造任何要复制的东西。在这种情况下,是的,尝试默认构造 ourDefaultInstance 将是未定义的行为。 @DavidHammen “默认复制构造函数”是默认构造函数(可以不带参数调用)和复制构造函数(可以使用相同类型的一个参数调用)。您可以根据需要添加任意数量的附加参数,只要它们都有默认参数即可。 刚刚偶然发现了这个。关于答案中的最后一句话:根据this 参考,在C++ 11 中,可以使用关键字default 强制生成隐式复制构造函数,尽管存在用户定义的复制构造函数。【参考方案2】:

没有默认的复制构造函数。有 默认构造函数和复制构造函数,它们是不同的 东西。

隐式定义的复制构造函数(我认为这是你 意思是“默认复制构造函数”)将复制非静态成员 使用它们的复制构造函数的类类型,而不是它们的默认值 构造函数。当您使用隐式定义的复制构造函数时 不要定义自己的复制构造函数。

【讨论】:

你确定你的第一段吗?在 AIs 的回答中查看我的 cmets。 @ChristianRau 查看这篇文章codewrangler.home.comcast.net/~codewrangler/tech_info/… 是的,它没有说明复制构造函数。如果存在任何构造函数,则仅不会生成 默认构造函数。我看到您可能将 OP 的术语 "default copy constructor" 误解为 default constructor (就像其他人似乎也这样做了),但另一方面我看不出如何不将其理解为隐式生成的复制构造函数。对于复制构造函数,您的第一段是完全错误的,因为如果没有 复制构造函数 存在,它们总是会生成,就像您在最后一段中所说的那样。 @ChristianRau 你最好问问original author。 Paragraph 2 and 3 @ChristianRau 这取决于他在第一段中想说什么。一旦为类定义了任何构造函数,就不再生成默认构造函数。这就是他的意思吗(其中“所有默认构造函数”表示“默认构造函数”,“变得不可用”表示“没有隐式声明的构造函数”)?或者他是否在制造他在第二段中解释的同样的困惑。【参考方案3】:

http://www.cplusplus.com/articles/y8hv0pDG/

如果您还没有定义一个默认的复制构造函数。所以是的,你可以调用默认的复制构造函数,如果你没有定义一个复制构造函数,但是如果你在你的类中定义了一个复制构造函数,你将无法调用默认的。

【讨论】:

我不明白你的最后一句话 - 你能把这个答案清理干净吗? Nim,默认情况下,编译器提供了一个拷贝构造函数。对于某些情况,您可能希望定义自己的复制构造函数,例如仅复制 10 个数据成员中的一个或两个数据成员(例如),或用于代码优化。如果你定义了自己的拷贝构造函数,编译器不会给类一个默认的拷贝构造函数。也可以通过定义复制构造函数来完全删除它(我不确定这个过程),以确保它不可用。希望这能解决问题吗? @Shane:后者不是真的。您可以删除它,是的,但仅限于 C++11。此外,它不是通过定义它来完成的,而是通过将其声明为=delete @MSalters:啊,听起来不错。正如我所说,不确定该过程,感谢您为我解决这个问题。 @MSalters,在 C++11 之前,你可以声明一个 private 复制构造函数来阻止其他人使用它。或者,甚至只是声明它但没有实现! T(const T&);

以上是关于我定义了一个非拷贝构造函数;复制构造函数是不是仍会被隐式定义?的主要内容,如果未能解决你的问题,请参考以下文章

拷贝构造函数

c++拷贝构造函数

拷贝构造函数

构造函数的调用规则

笔记十:复制构造函数深拷贝浅拷贝

复制构造函数与赋值运算符(=)有何不同