If at all possible, it's better to set data members via the initializer list, in which case there's no problem with arguments that shadow member names. Another alternative is to use this->foo = foo;
in the body of the constructor. A similar problem exists for setters, but now you can't use the initializer list solution. You're stuck with this->foo = foo;
-- or just use different names for arguments and members.
Some people really hate arguments that shadow data members; multiple coding standards explicitly say never to do this. Others think this kind of shadowing, at least for constructors and setters, is the cat's meow. I recall reading one or two coding standards (but I don't recall which) that designated this kind of shadowing as a "should" (but not "shall") practice.
One final option is to use shadowing in the function declaration so as to give readers a hint as to what the function does, but use distinct names in the implementation.
Update: What is "shadowing"?
#include <iostream>
void printi (int i) { std::cout << "i=" << i << "\n"; }
int i = 21;
int main () {
printi (i);
int i = 42;
printi (i);
for (int i = 0; i < 3; ++i) {
printi (i);
int i = 10;
printi (i);
}
printi (i);
}
The innermost declaration of i
, int i=10
, shadows the variable i
declared in the for
statement, which in turn shadows the variable i
declared at function scope, which in turn shadows the global variable i
.
In the problem at hand, the arguments x
, y
, width
, and height
to the non-default constructor for class A
shadow the member data with the same names as those arguments.
Your width=width;
did nothing because the argument width
shadows (hides) the data member width
. When you have two or more variables with the same name that were declared at different scopes, the winner is always the name with the innermost scope. In general, it is always the name with the innermost scope that wins.