Reputation: 3
Below is an example of what I am trying to do. Basically, my GetInt()
function is defined in the base class A
, and my derived class B
should also use the same definition. But the catch is that, when I access GetInt()
from an object of class B
, I want to return the derived class's member not the base's one. But the Output of below code gives:
Constructor A called
Constructor A called
Constructor B called
Object A: 10
Object B: 10
whereas I want it to be:
Constructor A called
Constructor A called
Constructor B called
Object A: 10
Object B: 5
My code:
class A{
public:
A(){
std::cout << "Constructor A called" << std::endl;
m_nA = 10;
}
int GetInt(){
return m_nA;
}
private:
int m_nA;
};
class B : public A{
public:
B(){
std::cout << "Constructor B called" << std::endl;
m_nA = 5;
}
private:
int m_nA;
};
int main(){
A ObjA; B ObjB;
std::cout << "Object A: " << ObjA.A::GetInt() << std::endl;
std::cout << "Object B: " << ObjB.B::GetInt() << std::endl;
return 0;
}
Is there any way to do this?
Upvotes: 0
Views: 131
Reputation: 244
Virtual function is a good option but You can also use this code.
class A{
public:
A(){
std::cout << "Constructor A called" << std::endl;
m_nA = 10;
}
int GetInt(){
return m_nA;
}
protected:
int m_nA;
};
class B : public A{
public:
B(){
std::cout << "Constructor B called" << std::endl;
m_nA = 5;
}
};
In this case when we call the Class B constructor it first call the class A constructor so initialize m_nA with 10. Then in body of class B constructor it override m_nA value with 5. So in this case always gives the correct result as you expected.
Upvotes: 1
Reputation: 36649
You need to make GetInt()
virtual and override it in the sub class:
class A{
public:
A(){
std::cout << "Constructor A called" << std::endl;
m_nA = 10;
}
virtual int GetInt(){
return m_nA;
}
private:
int m_nA;
};
class B : public A{
public:
B(){
std::cout << "Constructor B called" << std::endl;
m_nA = 5;
}
virtual int GetInt(){
return m_nA;
}
private:
int m_nA;
};
Constructor A called
Constructor A called
Constructor B called
Object A: 10
Object B: 5
Since you are explicitly calling the method by specifying the type A::
and B::
, you do not necessarily need to make it virtual - but you would then not be able to call B::GetInt()
through a pointer or reference to A
(no late binding):
A& ObjAb = ObjB;
std::cout << "Object B through A&: " << ObjAb.GetInt() << std::endl;
With virtual method:
Object B through A&: 5
With non-virtual method:
Object B through A&: 10
Upvotes: 0
Reputation: 927
private:
int m_nA;
Change the above in base class "A" to "protected". Don't define the member "m_nA" in "class B". Thats it! you are good to go.
Upvotes: 2
Reputation: 64293
You are calling A::GetInt()
, and that will always return A::m_nA
.
Unless you can change the name of B::m_nA
, the only thing you can do it to use virtual functions :
class A{
public:
A() : m_nA(10){
std::cout << "Constructor A called" << std::endl;
}
virtual int GetInt(){
return m_nA;
}
private:
int m_nA;
};
class B : public A{
public:
B() : A(), m_nA(5){
std::cout << "Constructor B called" << std::endl;
}
virtual int GetInt(){
return m_nA;
}
private:
int m_nA;
};
Upvotes: 1