Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Base and derived classes C++

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.

like image 584
QFi Avatar asked Mar 20 '17 16:03

QFi


People also ask

What are base and derived classes?

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.

How do you identify a base class and a 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.

What is a base class?

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).

What is base class and derived class in C#?

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.


2 Answers

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?

like image 97
Bathsheba Avatar answered Sep 24 '22 08:09

Bathsheba


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.

like image 34
izlin Avatar answered Sep 26 '22 08:09

izlin