Rajesh
Rajesh

Reputation: 1135

getting size of child object inside parent function

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

Answers (1)

Mihayl
Mihayl

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

Related Questions