【发布时间】:2012-06-27 07:22:11
【问题描述】:
class A {};
class B { public: B (A a) {} };
A a;
B b=a;
从技术上讲,这里是否在创建b 时应用了复制构造函数?
【问题讨论】:
-
这不是复制构造函数。复制构造函数将相同类型的对象作为参数。
标签: c++
class A {};
class B { public: B (A a) {} };
A a;
B b=a;
从技术上讲,这里是否在创建b 时应用了复制构造函数?
【问题讨论】:
标签: c++
是的,理论上。这是复制初始化。首先从初始化器 (a) 构造一个临时的 B 实例,然后通过复制构造函数从这个临时实例初始化 b。
编译器可以并且经常这样做,忽略临时和复制构造,并使用 B(A) 构造函数直接从 a 构造 b。
【讨论】:
=-initialization 等价于相应的构造函数调用,直到我尝试执行std::auto_ptr<T> p = new T; 并没有得到我预期的结果。顺便说一句,标准中的相应部分是 §8.5 [dcl.init] 第 16 段。
从技术上讲,这里是否在创建 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 隐式创建的复制构造函数也被调用。 :)
B b = a; 被转换为B b (a); 而我只是因为不想在我的初始化程序中有= 符号而感到很奇怪(所以人们不会认为重载的赋值在那里适用)。如果你说的是真的,那将是使用括号形式的更好理由,永远!
explicit,则不能在初始化时使用=。
不,复制构造函数会引用同类型的对象。
C++03 12.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
【讨论】:
A 和 B 的复制构造函数都会被调用。在将a 转换为B 时,将调用A 的复制构造函数来构造B(A) 的按值参数,然后将调用B 的复制构造函数来构造b 从临时B 由a 构造而成。
B (A& a) 会怎样?
a直接绑定B(A&)的引用参数(不允许复制a),只调用B的复制构造函数。
A 对象,为什么不直接从它创建一个B,而是从一个中介B?...
A 到B 的转换是由A 上的转换运算符而不是B 的转换构造函数提供的情况。
没有。它不是复制构造函数。
如果你通过初始化对象来创建一个对象,同一个类的对象,那就是复制构造函数。
A a;
A b=a;
以上代码是复制构造函数。
【讨论】: