首先是一些代码:
class CInner {
public:
CInner( const CInner& another ) { //impl here }
private:
// some member variables
}
class COuter {
public:
COuter( const CInner& inner ) : inner( inner ) {}
private:
CInner inner;
}
是的,在COuter::COuter( const CInner& )
中,参数与成员变量具有相同的名称。
在VC ++中有效 - VC ++认为用参数初始化成员变量是合理的,这就是发生的事情 - CInner::inner
用参数初始化。但是当使用GCC编译它时,它会以另一种方式解释:GCC用自己初始化CInner::inner
,因此它未被初始化。
哪个编译器是对的?
答案 0 :(得分:25)
这并不是某些特定的编译器决定什么是合理的,什么不是。语言规范明确指出在构造函数初始化列表中使用的inner(inner)
中,应该在类范围中查找第一个inner
(即解析为COuter::inner
),而第二个inner
应该在构造函数范围中查找(即解析为构造函数参数inner
)。
这就是您所描述的VC ++行为。但是,我发现很难相信GCC在这种情况下会表现不正确(除非你有一些奇怪的旧版GCC)。你确定你没有误解过GCC的行为吗?
答案 1 :(得分:12)
Visual C ++是正确的。我怀疑你正在使用旧版本的gcc进行测试 - 至少我记得,最近的那些正确地做到了这一点。这标准见§12.6.2/ 7,其中给出了以下示例:
class X {
int a;
int b;
int i;
int j;
public:
const int& r;
X(int i): r(a), b(i), i(i), j(this->i) {}
};
初始化X :: r以引用X :: a,使用构造函数的值初始化X :: b 参数i,用构造函数参数i,[...]
的值初始化X :: i