#ifndef header
#define header
struct base
{
private:
int p,q;
public:
base();
base(const base&);
base operator=(const base&);
~base();
};
struct der: public base
{
private:
int x,y;
public:
der();
der(const der&);
der operator=(const der&);
~der();
};
#endif
#include"10.h"
#include<iostream>
base::base()
{
std::cout<<"base ctor- 0 arg\n";
p=0; q=0;
}
base::base(const base &b)
{
std::cout<<"base copy ctor\n";
p=b.p;
q=b.q;
}
base base::operator=(const base &b)
{
std::cout<<"base overloaded=operator\n";
p=b.p;
q=b.q;
return *this;
}
base::~base()
{
std::cout<<"base dctor\n";
}
der::der()
{
std::cout<<"derived ctor- 0 arg\n";
}
der::der(const der &d)
{
std::cout<<"derived copy ctor\n";
x=d.x;
y=d.y;
}
der der::operator=(const der &d)
{
std::cout<<"derived overloaded operator\n";
x=d.x;
y=d.y;
return *this;
}
der::~der()
{
std::cout<<"derived dctor\n";
}
#include"10.h"
#include<iostream>
int main()
{
der d1,d2;
std::cout<<"\n";
d2=d1;
std::cout<<"\n";
der d3=d1;
std::cout<<"\n";
}
base ctor- 0 arg
derived ctor- 0 arg
base ctor- 0 arg
derived ctor- 0 arg
derived overloaded operator
base ctor- 0 arg
derived copy ctor
derived dctor
base dctor
base ctor- 0 arg
derived copy ctor
derived dctor
base dctor
derived dctor
base dctor
derived dctor
base dctor
1. How that 0-arg constructor of base class is calling when copy constructor and overload=operator of derived class called as I am not creating any base class object ?
2. why overloaded=operator of derived class not calling respective overloaded=operator of base class.
3. similarly with why copy constructor of derived class not calling respective copy constructor of base class.
Let us Analyze the 3 statements in the main program one by one.
We will discuss the second statement in the main program last, as that is the one that will require the maximum explanation
Statement-1: der d1, d2 This works as expected and first, the base class is constructed and then the derived class is constructed for both the objects.
Statement-3: der d3 = d1 Here we are trying to copy construct a der class object d3 from another der class object d1. But before the derived class object can be constructed, first the base class object needs to be created. There are 2 constructors in the base class, one is the default constructor and another is the copy constructor, how will the compiler choose which one to pick?
The answer is that we will need to tell the compiler as to which base class constructor to pick, and the way to tell this is by using the initialization list of the derived class constructor, and specifically calling the base class constructor you wish to be used.
der::der(const der &d):base(d)
{
std::cout<<"derived copy ctor\n";
x=d.x;
y=d.y;
}
In the code above, we are specifying how to construct the base class. The d reference will be upcast to base class reference for the call to base class copy constructor.
In your original version, the compiler will need a default base class constructor of the base, and which was exactly being called, as it was not specified as to how to construct the base class.
Statement-2: d2 = d1; In this statement, you are calling the assignment operator, which is defined as here
der der::operator=(const der &d)
{
std::cout<<"derived overloaded operator\n";
x=d.x;
y=d.y;
return *this;
}
Overloaded operators are nothing but functions, and a derived class function will not automatically call the base class function. If you need that base class version also be called then you will need to add the base class version of the call also in the function, to something like below
der der::operator=(const der &d)
{
base::operator=(d);
std::cout<<"derived overloaded operator\n";
x=d.x;
y=d.y;
return *this;
}
Once you make this change, now the base class operator= will also be called. However, if you now examine the output of the program it will confuse you even more. The output that this statement will now produce will be like below
base overloaded=operator
base copy ctor
base dctor
derived overloaded operator
base ctor- 0 arg
derived copy ctor
derived dctor
base dctor
Why are these constructors and destructors being called?
This is happening because the operator= function returns by value, which is not the right thing to do for the assignment operator. In the modified version of the derived class operator, we call base class operator base::operator=(d); This statement will call the below base class operator function
base base::operator=(const base &b)
{
std::cout<<"base overloaded=operator\n";
p=b.p;
q=b.q;
return *this;
}
However, this function returns by value, which will cause a temporary object of the base class to be created, which will then also be destructed immediately. After this, the derived class operator also returns by value, which will require a der class to be constructed, which will, in turn, require a base class to be constructed, and this will then also be destroyed immediately. Causing the messages which we see.
The right way to return from operator= will be returning the reference. Hence modify the base class and derived class operators to as below And also make the corresponding changes in the .h file.
base& base::operator=(const base &b)
{
std::cout<<"base overloaded=operator\n";
p=b.p;
q=b.q;
return *this;
}
der& der::operator=(const der &d)
{
base::operator=(d);
std::cout<<"derived overloaded operator\n";
x=d.x;
y=d.y;
return *this;
}
Once you modify the operator functions to as above the second statement will print as below.
base overloaded=operator
derived overloaded operator