Reputation: 463
#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
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
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 toX::a
, initializesX::b
with the value of the constructor parameteri
, initializesX::i
with the value of the constructor parameteri
, and initializesX::j
with the value ofX::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, thethis
pointer can be used in the expression-list of a mem-initializer to refer to the object being initialized. — end note ]
Upvotes: 2
Reputation: 69988
Because of below points, which all C++ compilers follow as rule:
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