I'm trying to implement the Flyweight pattern, but I'm not quite sure how inheritance works, and so I'm not quite sure how this pattern works.
Let's say I have a superclass that holds all the "heavy" information - textures, etc., the instrinsic information (the one that never changes).
class Block{
public: //for the sake of the example
Texture tex;
etc.
};
And I have the light class with data that changes:
class Block_light : public Block {
public:
int posX, posY, posZ;
int color;
etc.
};
So, if I in main create n Block_light
, will I be also creating n Block
or will they all be tied to one instance?
int main(){
std::vector<Block_light> blocks(n);
return 0;
};
Did I create n Block_light
and 1 Block
or n Block_light
and n Block
? If it's the latter, how can I make it so that it only uses one instance?
The C++ object model ensures that each instance of a subclass (i.e. derived class) contains also its own instances of all its superclasses (i.e. base classes).
In your case, this means that every Block_light
object will have all the Block_light
properties, as well as a Block
sub-object with all the Block
properties. In other words, Block_light
are not so light at all.
If you want to share a single common state:
Block_light
would not inherit from Block
but refer to a shared Block
object.Block
and Block_light
interchangeably, you could make both inherit from a common interface (i.e. a clss with only virtual functions and no state) IBlock
.The first option would look like:
class Block {...};
class Block_light { // no inheritance
shared_ptr<Block> b; // but (private) composition
...
};
The second option would be:
class IBlock { // no member variables
public:
virtual Texture get_texture()=0;
virtual ~IBlock(){};
};
class Block : public IBlock { // sharable state
Texture tex;
public:
Texture get_texture() override { return tex; }
};
class Block_light : public IBlock {
shared_ptr<IBlock> b; // or IBlock or Block depending on the needs.
public:
Block_light (shared_ptr<IBlock>i) : b(i) {}
Texture get_texture() override { return b->get_texture(); }
};
int main() { // just a perfectible quick example
auto myb=make_shared<Block>();
Block_light b1(myb);
b1.get_texture();
}
The last one would be used like this:
int main() { // just a perfectible quick example
Block myb; // shared part;
Block_light bl;
bl.get_texture(myb);
}
I will not enter into the details of the flyweight implementation but you have an example here. However think twice before opting for this pattern, since providing the shared context can be challenging and error prone.