Reputation: 1135
I want to know the size of the derived class object inside parent function. The parent function in my case is virtual and hence I cannot use sizeof(child class name) and I have to decide dynamically based on the object passed. Below is the code snippet. I used sizeof(*this) inside PrintBalance() of parent class and that will not work. I need something similar to that. I am explicitly calling parent class function from overridden child class.
class Account
{
protected:
int var1;
int var2;
double m_balance;
public:
Account( double d )
{
m_balance = d;
}
virtual double GetBalance()
{
return m_balance;
}
virtual void PrintBalance()
{
cout<<"size in Parent= "<< sizeof(*this)<<endl;
}
private:
};
class CurrentAccount : public Account
{
int var3;
int var4;
public:
CurrentAccount(double d) : Account(d) {}
void PrintBalance()
{
Account::PrintBalance();
cout<<"size in Derived = "<< sizeof(*this)<<endl;
cout << "Current account balance: " << GetBalance() << endl;
}
};
int main()
{
CurrentAccount cAcc(1000);
CurrentAccount *pCurrent = &cAcc ;
pCurrent->PrintBalance();
pCurrent->GetBalance();
}
Upvotes: 0
Views: 391
Reputation: 3911
You need a virtual method in the base class and override it in all derived classes returning the size of the class/type.
class Account
{
public:
//....
virtual size_t GetSizeOf() const
{
return sizeof(*this);
}
//....
virtual void PrintBalance()
{
std::cout << "size in Parent= " << this->GetSizeOf() << std::endl;
}
//...
};
class CurrentAccount : public Account
{
public:
//...
size_t GetSizeOf() const override
{
return sizeof(*this);
}
//...
void PrintBalance() override
{
Account::PrintBalance();
std::cout << "size in Derived = " << this->GetSizeOf() << std::endl;
// ...
}
};
So it should print the same size from both methods - http://coliru.stacked-crooked.com/a/37177e4e6e899090.
UPDATE
To print the members of all derived classes from the base you need a virtual method that allows the derived to extend the base.
EXAMPLE 1: Print derived class's members using override:
class Account
{
protected:
//....
virtual void DoPrint() const
{
std::cout << "print Account's members" << std::endl;
}
public:
//....
void PrintBalance()
{
//std::cout << "size in Parent= " << this->GetSizeOf() << std::endl;
DoPrint();
}
};
class CurrentAccount : public Account
{
protected:
//...
void DoPrint() const override
{
Account::DoPrint();
std::cout << "print CurrentAccount's members" << std::endl;
}
};
You could also change the base to use a dictionary or even a list of print callbacks.
Example 2: Print derived class's members without override: (http://coliru.stacked-crooked.com/a/56402cff02a922d2):
#include <functional>
#include <vector>
#include <iostream>
// not using namespace std;
class Account
{
protected:
int var1 = 1;
int var2 = 2;
double m_balance = 3.0;
public:
std::vector<std::function<void()>> printers; // Could be made static and pass `this` and as parameter
Account()
{
printers.emplace_back([this]() {
std::cout << "var1= "<< var1 << "\n"
<< "var2= "<< var2 << "\n"
<< "m_balance= "<< m_balance << std::endl;
});
}
//....
void PrintBalance()
{
for ( const auto& p : printers )
{
p();
}
}
//...
};
class CurrentAccount : public Account
{
protected:
int var3 = 4;
int var4 = 5;
public:
CurrentAccount(): Account() {
printers.emplace_back([this]() {
std::cout << "var3= "<< var3 << "\n"
<< "var4= "<< var4 << std::endl;
});
}
//...
};
Upvotes: 2