2012-01-13 164 views
1

我正在做对吗?这是我的代码高度简化的版本:在初始化列表中初始化引用对象成员

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)时执行什么?

+0

你自己的'Driver'提供一个构造函数接收'Logger'参考:'驱动器(记录器和采集器)' ,这是初始化参考成员的标准和常用方式。我不明白这个问题。 – 2012-01-13 11:09:31

+0

你不“叫”构造函数。永远。 – 2012-01-13 11:10:53

+1

顺便说一句,你不能复制流。 – 2012-01-13 11:11:21

回答

2

Logger的简单复制构造函数为您合成,除非您自己声明一个构造函数。

这与您如何为您合成简单的默认构造函数(如果您未声明默认的用户定义的构造函数)大致相同。


[C++11: 12.8/7]:如果类定义不明确声明拷贝构造函数,一个是隐式声明。如果类定义声明移动构造函数或移动赋值运算符,则隐式声明的复制构造函数 被定义为已删除;否则,它被定义为默认(8.4)。如果类具有用户声明的复制赋值运算符或用户声明的析构函数,则不推荐使用后一种情况。因此,对于类定义

struct X { 
    X(const X&, int); 
}; 

复制构造函数是隐式声明的。如果用户声明的构造将在后面定义为

X::X(const X& x, int i =0) { /* ... */ } 

然后任何使用X的拷贝构造是形成不良的,因为模糊的;不需要诊断。

[C++11: 12.8/8]:一类的隐式声明的拷贝构造函数X将有形式

X::X(const X&) 

如果

  • 每个直接或虚基类BX有交流OPY构造,其第一个参数是const B&型或const volatile B&的,和
  • X属于类型M(或其阵列)的所有非静态数据成员,每个这样的类型具有复制构造,其第一参数类型为const M&const volatile M&

否则,隐式声明的拷贝构造函数都会有形式

X::X(X&) 
2

当你构建一个DriverLogger的说法,它采取的是参考和复制Logger构造函数被调用来初始化m_logger,所以你最终得到一个新的Logger是争论的一个副本。复制构造函数由编译器提供,除非通过声明复制构造函数private明确地使Logger不可复制。

似乎完全有效,除了你应该使logger参数const参考;毕竟,你会复制它,而不是修改它。

+0

什么复制构造函数?我还没有定义'Logger'的复制构造函数。或者这是隐式完成的? – MBober 2012-01-13 11:09:43

+0

@MBober:如果没有明确定义,编译器会插入默认的拷贝构造函数。 – 2012-01-13 11:12:00