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 )
#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:-
Base,B,C,D,E
can't be template class. It will cause circular dependency for me.- I must be able to call base class's function from derived class (if any) e.g.
e->bFunction()
ande->cFunction()
, as usual.
However, it is OK if I can't calle->bField
anymore. - I still want the ease of declaration.
Currently, I can declare"E inherit from C and D"
asclass 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 :-
Aucun commentaire:
Enregistrer un commentaire