I am trying to let PrintVal()
of the base class print the value of private member m_val
of the derived class, but it appears it is still printing 1 instead of 2.
Since d
is a instance of derived
class, why didn't it print 2 instead?
#include <iostream>
class base
{
public:
void PrintVal()
{
std::cout << m_val <<std::endl;
}
private:
int m_val = 1;
};
class derived : public base
{
public:
// void PrintVal()
// {
// std::cout << m_val <<std::endl;
// }
private:
int m_val = 2;
};
int main()
{
derived d;
d.PrintVal();
return 0;
}
How to use PrintVal()
in the base class to print m_val
in the derived class? Thank you so much.
In your current code there are 2 separate variables: base::m_val
and derived::m_val
.
PrintVal()
is a method of base
and therefore accesses base::m_val
.
You can use a virtual method to get the value.
This virtual method in base
will return base::m_val
, and the override in derived
will return derived::m_val
.
PrintVal
in base
can call this virtual method to print the relevant value.
This is shown below:
#include <iostream>
class base {
public:
void PrintVal() {
// Use the virtual method to get the value:
std::cout << GetVal() << std::endl;
}
private:
virtual int GetVal() { return m_val; } // will return `base::m_val`
int m_val = 1;
};
class derived : public base {
public:
private:
int GetVal() override { return m_val; } // will return `derived::m_val`
int m_val = 2;
};
int main() {
derived d;
d.PrintVal();
}
Output:
2
If you have access to C++23, there's an elegant solution using a this auto& self
parameter (suggested by @WeijunZhou in a comment) but it will work only if you can make m_val
public in derived
:
#include <iostream>
class base {
public:
void PrintVal(this auto& self) {
std::cout << self.m_val <<std::endl;
}
private:
int m_val = 1;
};
class derived : public base {
public:
int m_val = 2;
};
int main() {
derived d;
d.PrintVal();
}
Note:
Unlike the 1st solution that uses dynamic dispatch, the 2nd one uses static dispatch.
The diferences can be seen if you add these 2 lines to main
:
base& b = d;
b.PrintVal();
The 1st solution will print 2
due to dynamic dispatch (because b
actually refers to a derived
) - see demo.
But the 2nd solution will print 1
because b
is defined as a reference to base
- see demo.