Reputation: 31
I have two classes in C++, where one inherits from the other:
class A {
public:
virtual void Initialize(){
m_MyString = "Default value";
}
protected:
string m_MyString;
}
class B : public A {
public:
void Initialize(){
A::Initialize();
m_MyString = "New Value";
}
}
Is there a difference between the above class B and this one?
class B : public A {
public:
void Initialize(){
A::Initialize();
A::m_MyString = "New Value";
}
}
It seem using the scoping operator will result in a the string having garbage, correct? I'm thinking when it overrides, the A::m_MyString is different than B::m_MyString. Does this even make sense?
I'm seeing the variable get set in A, then when we return to B, have garbage. This has to do with "hidden" vs. overridden?
Upvotes: 3
Views: 209
Reputation: 735
It seem using the scoping operator will result in a the string having garbage, correct?
No, this should work and m_MyString will have "New Value" after b.Initialize() is called.
I'm thinking when it overrides, the A::m_MyString is different than B::m_MyString. Does this even make sense?
No, when a class B inherits another class A, the object of class B will have a union of the data members of the two. In this case, there is only one m_MyString that is A::m_MyString.
I'm seeing the variable get set in A, then when we return to B, have garbage. This has to do with "hidden" vs. overridden?
No, there is only one instance of m_MyString.
You definitely need to read this - http://www.openrce.org/articles/files/jangrayhood.pdf.
Upvotes: 0
Reputation: 4017
If this is how your code looks:
using namespace std;
class A
{
public:
virtual void Initialize()
{
m_MyString = "Default value";
}
protected:
string m_MyString;
};
class B : public A
{
public:
void Initialize()
{
A::Initialize();
m_MyString = "New Value";
}
void display()
{
cout<<m_MyString<<endl;
}
};
int main()
{
B b;
A a;
b.Initialize();
b.display();
return 0;
}
Then there is no difference between the two versions of the class B that you described in your question. I added the display function just to make the values clear. By the definitions of the class that you have given, the m_MyString is not being overridden. So the m_MyString variable will have "New Value" assigned to it, i.e. both the classes A and B will share the variable m_MyString.
If you override the m_MyString in class B like
class B : public A
{
public:
void Initialize()
{
A::Initialize();
m_MyString = "New Value";
}
void display()
{
cout<<m_MyString<<endl;
}
protected:
string m_MyString;
};
Then the value of B::m_MyString will contain "New Value" and the Value of A::m_MyString will contain "Default value".
Upvotes: 0
Reputation: 897
Are you calling Initialize() from the constructor of A?
Calling virtual methods in constructors is not recommended. For example, if A's constructor looked like
A::A() {
Initialize();
}
B's Initialize method would never get called.
Seeing your actual code would help a lot.
Upvotes: 1
Reputation: 117
The compiler should tell you if you're calling a virtual function from a constructor. But if not, that's definitely a problem.
I think you can make a virtual function final in the derived class, but maybe not. The variable should be the same, regardless of whether or not you explicitly define scope, unless you have a variable of the same name in the derived class.
Upvotes: 0
Reputation: 99585
Your code is not valid in many ways. It should look like:
class A { // << errors were here
public:
virtual void Initialize(){
m_MyString = "Default value";
}
protected:
string m_MyString;
}; // << lost ;
class B : public A // << errors were here
{
public:
virtual void Initialize(){ // << virtual
A::Initialize(); // has no effect in the end
A::m_MyString = "New Value"; // same as `m_MyString = "New Value";`
}
}; // << lost ;
In the code above there is no difference with m_MyString
. Post your actual code with error.
If your code looks like:
class B : public A
{
public:
virtual void Initialize(){
// here is a difference
A::m_MyString = "New Value";
m_MyString = "New Value";
}
protected:
string m_MyString; // !!! overridden
};
Then there is a difference because B
has two instances of m_MyString
: A::m_MyString
and B::m_MyString
.
Upvotes: 1
Reputation: 20726
There is no difference between those two versions of class B. Is that the real code that you see garbage in?
Upvotes: 0