Some code first:
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;
}
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?
There's no problem with giving parameter names and instance variable names the same name.
The technique of having two (or more) constructors in a class is known as constructor overloading. A class can have multiple constructors that differ in the number and/or type of their parameters. It's not, however, possible to have two constructors with the exact same parameters.
Yes, its possible to use the same parameter name several times, given parameters have local scope.
The safest approach is to initialise every variable at the point of construction. For class members, your constructors should ensure that every variable is initialised or that it has a default constructor of its own that does the same.
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, [ ...]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With