A few days ago, I wanted to dive into the C++ world. I'm studying the base and derived class concepts. Could someone explain the nuance going on with the following two code snippets?
class A
{
private:
virtual int GetValue() { return 10; }
public:
int Calculate() { return GetValue()*1.5; }
};
class B: public A
{
private:
virtual int GetValue() { return 20; }
};
int main()
{
B b;
std::cout << b.Calculate() << std::endl;
return 0;
}
The output is 30 but 15 was expected
class A
{
private:
int m_data;
public:
A(): m_data(GetValue()) {}
int Calculate() { return m_data*1.5; }
virtual int GetValue() { return 10; }
};
class B: public A
{
public:
virtual int GetValue() { return 20; }
};
int main()
{
B b; A* ap;
ap=&b;
std::cout << ap->Calculate() << std::endl;
return 0;
}
The output is 15 but 30 was expected
Can someone explain and help me understand the reasoning? Something is wrong with my thinking on this concept, but I am unable to figure it out.
A base class is an existing class from which the other classes are derived and inherit the methods and properties. A derived class is a class that is constructed from a base class or an existing class. 2. Base class can't acquire the methods and properties of the derived class.
The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. A derived class can have only one direct base class. However, inheritance is transitive.
A base class is a class, in an object-oriented programming language, from which other classes are derived. It facilitates the creation of other classes that can reuse the code implicitly inherited from the base class (except constructors and destructors).
The class whose members are inherited is called the base class. The class that inherits the members of the base class is called the derived class. C# and . NET support single inheritance only. That is, a class can only inherit from a single class.
First case:
This is trivial. You have an instantiated instance of B
, and you compute return GetValue() * 1.5;
which uses B::GetValue()
as you've marked GetValue()
to be virtual
in the base class. Hence 20 * 1.5 is evaluated.
Second case:
Not so trivial. You are calling GetValue()
in the base member initialiser to set a value for m_data
. Standard C++ dictates that the base class GetValue()
method will be called in that case. (Informally think of this as being due to class B
not being constructed until class A
is fully constructed). Hence 10 * 1.5 is evaluated. Interestingly, if GetValue()
was pure virtual, then the behaviour of the program would have been undefined.
Reference: Why a virtual call to a pure virtual function from a constructor is UB and a call to a non-pure virtual function is allowed by the Standard?
Try the following code for the second example:
class A
{
private:
int m_data;
public:
A(): m_data(GetValue()) { std::cout << "Init m_data and A ";}
int Calculate() { return m_data*1.5; }
virtual int GetValue() { std::cout << "GetValue from A ";return 10; }
};
class B: public A
{
public:
B() { std::cout << "Init B "; }
virtual int GetValue() { std::cout << "GetValue from B"; return 20; }
};
int main()
{
B b; A* ap;
ap=&b;
std::cout << ap->Calculate() << std::endl;
return 0;
}
It is the same as you already have but with outputs. You should get GetValue from A Init m_data and A Init B 15
. I hope now you see why you have an output of 15
. With the outputs you should be able to reconstruct the execution order.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With