从参考复制构建

发布于 2024-12-15 18:03:34 字数 159 浏览 0 评论 0原文

考虑这段代码

class Foo {
private:
    Bar bar; //note: no reference

public:
   Foo(Bar& b) : bar(b) { }
};

Bar 会被复制构造吗?

Consider this code

class Foo {
private:
    Bar bar; //note: no reference

public:
   Foo(Bar& b) : bar(b) { }
};

Will Bar get copy-constructed?

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

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

发布评论

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

评论(2

篱下浅笙歌 2024-12-22 18:03:34

这取决于 Bar 的公共构造函数的签名(显式或隐式定义)。

首先,C++ 标准允许引用的隐式转换,只要基础类型的唯一区别是目标类型至少与源类型一样cv 限定,使用部分此表中定义的顺序(C++11,§3.9.3/4):

没有简历限定 常量
没有简历限定 易失性
没有简历限定 常量易失性
const         < 常量易失性
易失性    < 常量易失性


因此,考虑到这一点以及§12.8/2:

如果类 X 的第一个参数的类型为 X&const X&,则该类的非模板构造函数是复制构造函数, 易失性 X&const 易失性 X&,并且要么没有其他参数,要么所有其他参数都有默认参数。

如果 Bar 的构造函数具有以下签名中的任何

Bar(Bar&);
Bar(Bar const&);
Bar(Bar volatile&);
Bar(Bar const volatile&);

那么是的,b 将被复制构造为 Foo::bar


编辑: 这是不正确的,我正在考虑 operator= 以及移动赋值运算符资格的详细信息。

请注意可以有一个不是复制构造函数的合格构造函数:

Bar(Bar);

这可以工作(读取:编译),但从技术上讲它不是复制构造函数。

That depends on the signatures of Bar's public constructors, either explicitly or implicitly defined.

To start with, the C++ standard allows for implicit conversion of references as long as the only difference in the underlying type is that the destination type is at least as cv-qualified than the source type, using the partial ordering defined in this table (C++11, §3.9.3/4):

no cv-qualifier < const
no cv-qualifier < volatile
no cv-qualifier < const volatile
const          < const volatile
volatile    < const volatile

So, taking that into account as well as §12.8/2:

A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments.

if Bar has a constructor with any of the following signatures:

Bar(Bar&);
Bar(Bar const&);
Bar(Bar volatile&);
Bar(Bar const volatile&);

then yes, b will be copy-constructed into Foo::bar.


EDIT: This was incorrect, I was thinking of operator= and the details of qualifying as a move-assignment operator.

Note that it's possible to have an eligible constructor that is not a copy constructor:

Bar(Bar);

This will work (read: compile), but it is not technically a copy constructor.

ぶ宁プ宁ぶ 2024-12-22 18:03:34

是的,您的成员变量 bar 将被复制构造,这是使用初始值设定项列表的好处之一,而不是在构造函数主体中分配值。

如果 Bar 类没有可访问的复制构造函数,并且编译器无法生成默认复制构造函数,则代码将无法编译。

当您将引用传递给复制构造函数时,通常应该将其设为 const 引用。

Yes your member variable bar will be copy constructed, that's one of the benefits of using an initializer list as opposed to assigning the value in the body of the constructor.

If the Bar class does not have an accessible copy constructor and the compiler can't generate a default one, the code will fail to compile.

When you pass a reference to a copy constructor, you should generally make it a const reference.

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