使用初始化列表中的引用初始化对象成员
Initialize object member with reference in initialization list
我这样做对吗?这是我代码的高度简化版本:
class Logger {
public:
Logger(std::ostream) { /*...*/}
};
class Driver {
public:
Driver() : m_logger(std::cout) {}
Driver(Logger& logger) : m_logger(logger) {}
private
Logger m_logger;
};
所以我的类Driver
有一个类型为Logger
的成员。当我调用无参数构造函数Driver()
时,Driver
的实例会使用std::cout
创建自己的Logger
实例。
调用Driver(Logger)
时,实例应使用已存在的Logger
实例作为引用。
上面的代码使用g++编译。虽然我理解调用Driver()
时会发生什么,但我不明白调用Driver(Logger)
时会发生怎样的情况。Logger
没有接受对Logger
的引用作为参数的构造函数("复制构造函数")。那么调用Driver(Logger)
时执行了什么呢?
除非您自己声明,否则Logger
的一个普通复制构造函数是为您合成的。
这与为您合成普通默认构造函数的方式非常相似(如果您没有声明默认用户定义构造函数)。
[C++11: 12.8/7]:
如果类定义没有显式声明复制构造函数,则隐式声明一个如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制构造函数定义为已删除;否则,它被定义为默认值(8.4)。如果类具有用户声明的复制赋值运算符或用户声明的析构函数,则不赞成使用后一种情况。因此,对于类定义struct X { X(const X&, int); };
复制构造函数是隐式声明的。如果用户声明的构造函数后来被定义为
X::X(const X& x, int i =0) { /* ... */ }
则CCD_ 16的复制构造函数的任何使用都是由于歧义而形成的;不需要进行诊断。
[C++11: 12.8/8]:
类X
的隐式声明的复制构造函数的形式为X::X(const X&)
如果
X
的每个直接或虚拟基类B
具有复制构造函数,该复制构造函数的第一参数是类型const B&
或const volatile B&
,以及- 对于类类型为
M
(或其数组)的X
的所有非静态数据成员,每个此类类类型都具有第一参数为const M&
或const volatile M&
类型的复制构造函数否则,隐式声明的复制构造函数将具有形式
X::X(X&)
当您使用Logger
参数构造Driver
时,它将被引用,并调用Logger
副本构造函数来初始化m_logger
,因此您最终得到一个新的Logger
,它是该参数的副本。复制构造函数由编译器提供,除非通过声明复制构造函数private
显式使Logger
不可复制。
似乎完全有效,只是您应该将logger
参数作为const
引用;毕竟,你要复制它,而不是修改它。
- C++在构造函数处用表达式初始化引用
- 我可以从取消引用"new"的返回值初始化引用吗
- 通过用户定义的转换初始化引用
- 为什么我可以在初始化引用后重新绑定引用?
- TBB 编译器错误 -"my_task":必须初始化引用
- Visual Studio 2017 允许在构造函数中使用自身初始化引用成员.真的是合法的C++吗?
- 为构造函数初始化引用实例变量提供默认值
- 在构造过程中获取类成员的未初始化引用是否合法
- 在C++中初始化引用
- 在动态分配的结构中初始化引用
- 使用三元运算符初始化引用变量
- 如何在 c++ 中显式初始化引用
- 初始化引用时何时以及为何获得副本
- 初始化C++引用-为什么不使用运算符的地址
- 在C++中初始化引用和变量
- 在函数参数中分配/初始化引用
- 在 C++ 中初始化引用不起作用,但初始化 const 引用有效,为什么?
- 类组合构造函数 d 必须显式初始化引用成员
- 用对tuple的引用初始化引用的元组
- 为什么在c++中不能重新初始化引用