我可以显式调用复制构造函数吗?

发布于 2024-08-20 15:57:40 字数 234 浏览 6 评论 0原文

我对复制构造函数的机制有点困惑。如果我错了,请纠正我:

如果一个方法将对对象的引用作为参数,并且该类定义了一个复制构造函数,则该类使用构造函数创建自身的副本,并将其传递给函数而不是对原始对象的引用?

此外,可以调用

Object * obj = new Object(&anotherObject);

创建 anotherObject 的副本吗?

I'm a little confused as to the mechanics of the copy constructor. Correct me if I'm wrong:

If a method takes a reference to an object as a parameter, and the class defines a copy construtor, then the class uses the constructor to create a copy of itself and that gets passed to the function instead of a reference to the original object?

Furthermore, one can call

Object * obj = new Object(&anotherObject);

to create a copy of anotherObject?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

不醒的梦 2024-08-27 15:57:41

复制构造函数仅在按值传递时调用,而不是按引用传递。通过引用,不需要复制(这是引用的一部分!),因此不会调用复制构造函数。

Copy constructor is called only when passing by value, not by reference. By reference no copying is needed (this is part of what references are for!) so no copy constructor called.

陪我终i 2024-08-27 15:57:40

不,如果一个函数需要引用:

void f1( Object & o );   // call by reference

那么就不会进行任何复制。如果函数接受一个值:

void f2( Object o );   // call by value

则编译器使用复制构造函数创建一个副本。

是的,当您说:

Object * obj = new Object(anotherObject);   // not &anotherObject

显式使用复制构造函数(假设 anotherObject 是 Object 类型。)这里使用 new 并没有什么神奇之处 - 在这种情况下:

Object obj2(anotherObject);

复制构造函数是也用过。

No, if a function take a reference:

void f1( Object & o );   // call by reference

then no copy is made. If a function takes a value:

void f2( Object o );   // call by value

then a copy is created by the compiler using the copy constructor.

And yes, when you say:

Object * obj = new Object(anotherObject);   // not &anotherObject

the copy constructor is used explicitly (assuming anotherObject is of type Object.) There is nothing magic about the use of new here, however - in this case:

Object obj2(anotherObject);

the copy constructor is also used.

太阳哥哥 2024-08-27 15:57:40

如果方法将对对象的引用作为参数,则不会调用复制构造函数。如果是这种情况,那么对复制构造函数本身的调用将导致无限循环(因为它采用引用作为参数)。

该行不是调用复制构造函数的有效方法。它期望引用作为参数,而不是指针。

If a method takes a reference to an object as a parameter, copy constructor will not be called. If that was the case, then a call to the copy constructor itself would have resulted in an infinite loop (since it takes a reference as an argument).

That line is not a valid way to call a copy constructor. It expects a reference as an argument, not a pointer.

我是男神闪亮亮 2024-08-27 15:57:40

您进行方法调用的事实在这里并不重要。函数调用期间的引用参数初始化与独立引用初始化没有什么不同,并且受相同规则的约束。

引用初始化的规则有点复杂,但底线是,如果初始值设定项是左值(在您的情况下是方法调用中的参数)并且引用的类型与初始值设定项的类型相同(即参数的类型与实参类型相同),则引用将直接绑定。即没有创建副本。

Object a; // class type
Object &r = a; // no copying
const Object &cr = a; // no copying

如果不满足这些要求(例如,如果初始化器是右值),那么这一切都取决于。在某些情况下,复制可能并且将会发生。例如,

const Object &tr = Object();

编译器可以将其解释为

const Object &tr = Object(Object(Object(Object())));

依赖于实现的有限数量的复制。当然,出于效率原因,编译器通常会尝试不创建不必要的副本,即使允许它们复制也是如此。

一个经常引起关于编译器复制行为有效性争论的经典例子是像下面这样的表达式中的引用初始化。

Object a;
const Object &r = <some condition> ? a : Object();

熟悉 C++ 引用语义的人会理解像上面这样的表达式很可能是标准权限背后的基本原理。在引用初始化期间执行多余的复制。

The fact that you are making a method call is of no importance here. Reference parameter initialization during a function call is no different from a standalone reference initialization and is governed by the same rules.

The rules of reference initialization are a bit complicated, but the bottom line is that if the initializer is an lvalue (the argument in the method call in your case) and the type of the reference is the same as the type of the initializer (i.e. type of the parameter is the same as the argument type), then the reference will be bound directly. I.e. no copy is created.

Object a; // class type
Object &r = a; // no copying
const Object &cr = a; // no copying

If these requirements are not met (like if the initializer is an rvalue, for example), then it all depends. In some cases the copying might and will take place. For example

const Object &tr = Object();

can be interpreted by the compiler as

const Object &tr = Object(Object(Object(Object())));

with implementation-dependent finite number of copyings. Of course, for efficiency reasons compilers normally are trying not to create unnecessary copies, even when they are allowed to copy.

A classic example that often stirs debate about the validity of the copying behavior of the compiler is the reference initialization in expressions like the following one

Object a;
const Object &r = <some condition> ? a : Object();

A person familiar with C++ reference semantics would understand that expressions like the above are likely the rationale behind the standard permission to perform superfluous copying during reference initialization.

苏别ゝ 2024-08-27 15:57:40

是的,使用新的放置位置,如下所示:

Object dstObject;
new(&dstObject) Object(&anotherObject);

yes using placement new like so:

Object dstObject;
new(&dstObject) Object(&anotherObject);
可是我不能没有你 2024-08-27 15:57:40

两种情况都没有。在第一种情况下,传递对该对象本身的引用,并且不创建副本。在第二种情况下,您将指针传递给 object 的构造函数,因此不会创建副本。所以对象应该有一个构造函数(而不是复制构造函数),类似于 object(anotherClass*)

No in both the cases. In the first case, reference to that object itself is passed and copy is not created. In the second case you are passing a pointer to the constructor of object hence no copy is created. So object should have a constructor (not a copy constructor) which is something like object(anotherClass*)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文