【问题标题】:Is this a copy constructor?这是一个复制构造函数吗?
【发布时间】:2012-06-27 07:22:11
【问题描述】:
class A {};
class B { public: B (A a) {} };

A a;
B b=a;

从技术上讲,这里是否在创建b 时应用了复制构造函数?

【问题讨论】:

标签: c++


【解决方案1】:

是的,理论上。这是复制初始化。首先从初始化器 (a) 构造一个临时的 B 实例,然后通过复制构造函数从这个临时实例初始化 b

编译器可以并且经常这样做,忽略临时和复制构造,并使用 B(A) 构造函数直接从 a 构造 b

【讨论】:

  • +1 到目前为止只有正确答案。我也一直认为=-initialization 等价于相应的构造函数调用,直到我尝试执行std::auto_ptr<T> p = new T; 并没有得到我预期的结果。顺便说一句,标准中的相应部分是 §8.5 [dcl.init] 第 16 段。
【解决方案2】:

从技术上讲,这里是否在创建 b 时应用了复制构造函数?

是的……但可能不是你想的那样。 A 的复制构造函数在创建 b 时被调用,以便将参数 A a 的值传递作为 B 构造函数的参数。

然而,在b的创建过程中并没有运行B的拷贝构造函数。


编辑:每天都会学到新东西。显然,从技术上讲,正如@CharlesBailey 指出的那样......如果您使用B b = a; 语法(“复制初始化”)而不是B b (a); 语法(“直接初始化”),则类型为 B 可能需要创建。此时 B 的复制构造函数将被调用。

研究这个现象有点难,但查尔斯指出 gcc 有一个-fno-elide-constructors 选项(也:Wikipedia on Copy Elision)@JesseGood 的链接有详尽的解释和一些演示代码:

Is there a difference in C++ between copy initialization and direct initialization?

【讨论】:

  • 技术上B b = a; 等价于B b(B(a)),所以B 隐式创建的复制构造函数也被调用。 :)
  • @GManNickG 我不明白为什么,看看 B 如何直接从 A 获得转换构造函数......
  • @GManNickG 真的吗?我一直认为B b = a; 被转换为B b (a); 而我只是因为不想在我的初始化程序中有= 符号而感到很奇怪(所以人们不会认为重载的赋值在那里适用)。如果你说的是真的,那将是使用括号形式的更好理由,永远!
  • 如果构造函数是explicit,则不能在初始化时使用=
  • @HostileFork:复制初始化,其中初始化程序与正在初始化的对象的类型不同,并且正在初始化的类型不是引用类型,需要将初始化程序转换为正确的临时然后用于直接初始化正在构造的对象的类型。如果可能的话,允许编译器消除临时和复制(或移动)并将其简化为简单的直接初始化,但不是必须的。
【解决方案3】:

不,复制构造函数会引用同类型的对象。

C++03 12.1 构造函数

  1. X 类的复制构造函数是第一个参数类型为X&const X& 的构造函数。

编辑:好的,公平地说(在阅读其他答案之后),正在调用 a 复制构造函数,但它是A 的复制构造函数。我以为你的意思是B's。

EDIT2:为了公平起见,根本没有必要调用它:

A a;
B b = a;   //called
B c = A(); //probably not called due to copy elision

【讨论】:

  • 后期编辑:从技术上讲,AB 的复制构造函数都会被调用。在将a 转换为B 时,将调用A 的复制构造函数来构造B(A) 的按值参数,然后将调用B 的复制构造函数来构造b 从临时Ba 构造而成。
  • @CharlesBailey 什么?哇不知道。如果我们改用B (A& a) 会怎样?
  • 然后a直接绑定B(A&)的引用参数(不允许复制a),只调用B的复制构造函数。
  • @CharlesBailey 但为什么呢?你已经有一个A 对象,为什么不直接从它创建一个B,而是从一个中介B?...
  • 这些是规则。但是考虑一下从AB 的转换是由A 上的转换运算符而不是B 的转换构造函数提供的情况。
【解决方案4】:

没有。它不是复制构造函数。

如果你通过初始化对象来创建一个对象,同一个类的对象,那就是复制构造函数。

A a;
A b=a;

以上代码是复制构造函数。

【讨论】:

    猜你喜欢
    • 2022-01-09
    • 1970-01-01
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    • 2012-04-29
    相关资源
    最近更新 更多