ProgEnthu
ProgEnthu

Reputation: 463

Initialization lists,local variables vs data members

#include <iostream>
using namespace std;
class Ex {
private:
    int i;
    float f;
public:
    Ex(int i,float f):i(i),f(f) {
        cout << this->i << '\t' << this->f << endl;
    }
    ~Ex(){
        cout << "destructor";
    }
};
int main() {
    Ex i(10,20.1f);
}

In the program above I wrote above,if the constructor was parameterized constructor like the following:

Ex(int i,float f){
        i=i;
        f=f;
        cout << this->i << '\t' << this->f << endl;
    }

here the data members of the object are initialized to junk because data members are hidden due to local variables of same name. But in the program above it works fine without explicit this.How?

Upvotes: 0

Views: 1359

Answers (3)

Konstantin Dinev
Konstantin Dinev

Reputation: 34895

The compiler is designed to work with the left-hand i and f as members of the class scope and the right-hand i and f as members of the constructor scope.

Upvotes: 0

jogojapan
jogojapan

Reputation: 69977

Similar questions have been asked before, e.g. here and here, but while many answers point out that this is (contrary to what Konstantin D - Infragistics says) not compiler-specific, I couldn't find any answer that actually quotes the relevant parts of the Standard.

So here they are. I've added emphasis to highlight the key statements.

(§12.6.2/10) In a non-delegating constructor, initialization proceeds in the following order:

— First, and only for the constructor of the most derived class (1.8), virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list.
— Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).
— Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).
— Finally, the compound-statement of the constructor body is executed.

(§12.6.2/12) Names in the expression-list or braced-init-list of a mem-initializer are evaluated in the scope of the constructor for which the mem-initializer is specified. [ 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, and initializes X::j with the value of X::i; this takes place each time an object of class X is created. — end example ]
[ Note: Because the mem-initializer are evaluated in the scope of the constructor, the this pointer can be used in the expression-list of a mem-initializer to refer to the object being initialized. — end note ]

Upvotes: 2

iammilind
iammilind

Reputation: 69988

Because of below points, which all C++ compilers follow as rule:

  1. Constructor initializer list can only exist with a class constructor
  2. In initializer list only the same class member and the base class constructor can be called
  3. Initialization happens in the same order as the class data member are declared

When compiler looks at i and f as part of initializer list, it immediately identifies as the class member and the things goes fine (point no. 2).
If you try anything else other than i and f, compiler will give error.

In 2nd case where you do assignment, compiler has 2 candidates for i and f. Either it can be a class member or a local variable. Since local variables are in inner most scope, compiler consider i as i and not this->i.

Upvotes: 1

Related Questions