lundi 10 juin 2019

reduce size of object in Multi virtual inheritance

After profiling, I found that a large portion of memory of my program are wasted by multi-virtual-inheritance.

This is MCVE to demostrate the problem ( http://coliru.stacked-crooked.com/a/0509965bea19f8d9 )

enter image description here

#include<iostream>
class Base{
    public: int id=0;  
};
class B : public virtual Base{
    public: int fieldB=0;
    public: void bFunction(){
        //do something about "fieldB"     
    }
};
class C : public virtual B{
    public: int fieldC=0;
    public: void cFunction(){
        //do something about "fieldC"     
    }
};
class D : public virtual B{
    public: int fieldD=0;
};
class E : public virtual C, public virtual D{};
int main (){
    std::cout<<"Base="<<sizeof(Base)<<std::endl; //4
    std::cout<<"B="<<sizeof(B)<<std::endl;       //16
    std::cout<<"C="<<sizeof(C)<<std::endl;       //32
    std::cout<<"D="<<sizeof(D)<<std::endl;       //32
    std::cout<<"E="<<sizeof(E)<<std::endl;       //56
}

I hope sizeof(E) to be not much more than 16 bytes (id+fieldB+fieldC+fieldD).
From experiment, if it is non virtual inheritance, E's size will be 24 (MCVE).

How to reduce size of E (by C++ magic, change program architecture, or design pattern)?

Requirement:-

  1. Base,B,C,D,E can't be template class. It will cause circular dependency for me.
  2. I must be able to call base class's function from derived class (if any) e.g. e->bFunction() and e->cFunction(), as usual.
    However, it is OK if I can't call e->bField anymore.
  3. I still want the ease of declaration.
    Currently, I can declare "E inherit from C and D" as class E : public virtual C, public virtual D easily.

I am thinking about class E: public SomeTool<C,D>{}, but not sure how to make it works.

To make things easier :

  • In my case, every class is used like it is monolith, i.e. I will never cast object between types like static_cast<C*>(E*) or vise versa.
  • Macro is allowed, but discouraged.
  • Pimpl idiom is allowed. Actually, below is what I daydream.
    However, with all the requirements, I can't find a way to code it :-

enter image description here

Aucun commentaire:

Enregistrer un commentaire