Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What if a constructor parameter has the same name as a member variable in C++?

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?

like image 821
sharptooth Avatar asked Feb 09 '10 06:02

sharptooth


People also ask

Can parameter have same name as variable?

There's no problem with giving parameter names and instance variable names the same name.

Is it possible for a constructor to have a same number of parameters?

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.

Can parameters have the same name?

Yes, its possible to use the same parameter name several times, given parameters have local scope.

Should a constructor initialize all members?

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.


2 Answers

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 innershould 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?

like image 90
AnT Avatar answered Sep 29 '22 03:09

AnT


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, [ ...]

like image 35
Jerry Coffin Avatar answered Sep 29 '22 03:09

Jerry Coffin