Reputation: 129
I want to have a class member to be an instance of another class. But I get a warning "warning C4458: declaration of 'x' hides class member" and the code does not work.
class Ca {
int va = 5;
public:
Ca();
int getVa(void);
};
int Ca::getVa(void) {
return va;
};
class Cb {
Ca x;
public:
Cb();
int getCa(void);
};
Cb::Cb(void) {
Ca x; // instanciate Ca
}
int Cb::getCa(void) {
return x.getVa();
}
int main()
{
Cb cb; // instanciate Cb
int i = cb.getCa();
cout << "va = " << i << endl;
}
I do not understand the warning, please could someone explain?
Upvotes: 1
Views: 6723
Reputation: 457
If you wanna to instanciate Class in the constructor, you can use like this:
class Ca {
int va = 5;
public:
Ca();
int getVa(void);
};
int Ca::getVa(void) {
return va;
};
class Cb {
std::unique_ptr<Ca> x;
public:
Cb();
int getCa(void);
};
Cb::Cb(void) {
x.reset(new Ca()); // Instanciate (Requires c++03 or newer)
}
int Cb::getCa(void) {
return x->getVa();
}
int main()
{
Cb cb; // instanciate Cb
int i = cb.getCa();
cout << "va = " << i << endl;
}
Upvotes: 0
Reputation: 42944
You have a problem here:
Cb::Cb(void) { Ca x; // instanciate Ca }
Since Ca x
is already defined as data member of class Cb
, there is a "conflict" with the local variable you defined above inside the Cb
constructor. The "conflict" is that the local variable Ca x
"hides" the data member Ca x
. While this code would compile, it is very error prone, and this situation is better avoided.
If your intent was to initialize the Ca x
data member, you don't have to do anything in Cb
default constructor: C++ does the initialization automatically. So you can just remove the Ca x;
line in Cb
's constructor.
EDIT As @Jesper wrote in his comment, and I completely agree with him, since this is C++ and not C, consider eliminating the void
from an empty parameter list.
Upvotes: 3
Reputation: 19761
Your class Cb
has a member variable named x
defined here:
Ca x;
But then in your constructor, you declare a different variable named x
:
Ca x; // instanciate Ca
While this is technically fine, when you reference a variable in a class member function, when you refer to a member variable by name, usually you want to refer to the member variable, but in this case, since there's a local variable with the same name you wind up referring to the local variable.
This is a VERY common way to get difficult to identify errors and so it is a very good idea to heed the warning and not duplicate the name.
Upvotes: 1
Reputation: 1710
You declare Ca x in the class Cb definition, then in the Cb constructor, you declare a new variable rather than using the one already defined.
Upvotes: 5
Reputation: 726579
The warning is on this line:
Cb::Cb(void) {
Ca x; // <<== Here
}
The problem is that Ca x
is a local variable unrelated to member variable x
.
If all you need is to call the default constructor to initialize x
, you don't have to do anything: C++ will do it for you automatically. If you would like to pass some parameters to Ca
's constructor, use initializer list:
Cb::Cb(int argForAsConstructor) : x(argForAsConstructor) {
// Empty body
}
The construct after the colon lets you initialize members variables that do not have default constructors.
Upvotes: 8