Some code first:
class CInner {
public:
CInner( const CInner& another ) { //impl here }
private:
// some member variables
}
class COuter {
public:
COuter(开发者_StackOverflow中文版 const CInner& inner ) : inner( inner ) {}
private:
CInner inner;
}
Yes, in COuter::COuter( const CInner& )
the parameter has the same name as the member variable.
In VC++ that works - VC++ gets the idea that it is only reasonable to initialize the member variable with the parameter and that's what happens - CInner::inner
gets initialized with the parameter. But when the same is compiled with GCC it is interpreted in another way: GCC initializes CInner::inner
with itself and so it is left uninitialized.
Which of the compilers is right?
It is not really about some specific compiler deciding what's reasonable and what's not. The language specification explicitly says that in inner(inner)
used in the constructors initializer list the first inner
should be looked up in class scope (i.e. resolve to COuter::inner
), while the second inner
should be looked up in the constructor scope (i.e. resolve to constructor parameter inner
).
This is what you described as VC++ behavior. However, I find it hard to believe that GCC would behave incorrectly in this case (unless you have some weird old version of GCC). Are you sure you haven't misinterpreted GCC's behavior somehow?
Visual C++ is correct. I suspect you're using an older version of gcc for your test -- at least as I recall, recent ones do this correctly. This is covered in §12.6.2/7 of the standard, which gives the following example:
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) {}
};
initializes X::r to refer to X::a, initializes X::b with the value of the constructor parameter i, initializes X::i with the value of the constructor parameter i, [ ...]
精彩评论