object, inheritance, dynamic_cast need advice - c++

I know that has been asked a lot, I googled but couldn't put everything together. Maybe because it is not possible to do, what I want?
I have
struct Universe
{
}
and
struct Atom: Universe
{
}
struct Molecule: Universe
{
}
Universe U;
Atom A;
Molecule M;
_atoms = vector<Universe*>(3);
_atoms.push_back(&U);
_atoms.push_back(dynamic_cast<Universe*>(&A));
_atoms.push_back(dynamic_cast<Universe*>(&M));
auto THIS_IS_ATOM = _atoms[1];
This code is most likely wrong in many ways. But my idea was to store different derived structs like this, and later access them from array or list, without any dataloss or class truncating. I wanted to get some element from array, like _atoms[1], and be able to know what type this struc is (Universe, or Atom) and e.t.c
How should I do it properly in C++?

Your code has several problems.
Universe needs a virtual destructor.
You must create your instances on the heap.
You are using the wrong std::vector constructor.
Here is a solution that should work:
struct Universe {
virtual ~Universe() {} // otherwise Atom and Molecule will not be deleted properly
}
struct Atom : Universe {
}
struct Molecule : Universe {
}
std::vector<Universe*> _atoms; // you don't need to pass anything in the constructor
_atoms.reserve(3); // but if you want to make sure that the vector has exactly a capacity of 3, use this
_atoms.push_back(new Universe());
_atoms.push_back(new Atom());
_atoms.push_back(new Molecule());
auto this_is_atom = _atoms[1]; // will actually be equivalent to
Universe* this_is_atom = _atoms[1];
// finally you must delete all the instances which you created on the heap
while (!_atoms.empty()) delete _atoms.back(), _atoms.pop_back();
Addendum: If you need to treat the objects in the vector non-polymorphically, you can cast them to the appropriate types with a static cast:
Atom* a = static_cast<Atom*>(_atoms[1]);
Edit: Instead of using a vector of raw pointers, it is advisable to use a vector of smart pointers instead, for example std::unique_ptr or std::shared_ptr, depending on the ownership semantics you are trying to model.

Related

Using different array-types interchangeably

I'm sure this question has been answered somewhere, but I'm not sure, what to even search for:
Say I have a class that stores some data in a std::vector, but I want to be able to use two differenct types interchangeably (for example to save memory) depending on the "mode" I set the class to. Something like this:
class MyClass
{
int Mode; // Could be, say, 0 or 1
std::vector<float> MyData; // Use this when Mode is 0
std::vector<short> MyData; // Use this when Mode is 1
void DoStuffWithData()
{
// ...
}
}
I know, this could probably be done with template, but I have not yet managed to wrap my head around this (if anybody could give me an example, please do so). Of course I could work with overloaded functions and use a lot of if-statements to switch between the cases or use a void-pointer that is set to one of the vectors and then cast to its type, but I think, this would make pretty messy code.
What would be a nice and clean way to use (mostly) the same code by just referring to MyData?
Edit
Mode would change during runtime. Basically the class would record and work with data it collects in the background. I want to be able to just change Mode for a new "recording" (of which I might start multiple during runtime). This would then set both vectors to size zero and use the one selected. Again - I know, I could overload functions and just use some if-statements, but I would like to keep the code short and clean (and maybe learn some things along the way).
You can't have two members called MyData. You can use templates instead, as that's essentially what they're meant for. This would be a simple example:
template<class T>
class MyClass {
std::vector<T> MyData;
void DoStuffWithData()
{
// ...
}
};
int main() {
MyClass<short> shortData;
MyClass<float> floatData;
MyClass<long> longData; // you're no longer limited to just two types
// ...
return 0;
}
Notice there's no Mode anymore, as you'll just choose the desired type when declaring each variable.

Saving in binary files

I've been working on a project for the past few days that involves three linked lists.
Here is an example of the header with the nodes and the lists themselves:
class nodeA
{
int data1;
double data2;
nodeA* next;
}
class listA
{
nodeA* headA;
...
}
class nodeB
{
int data3;
double data4;
nodeB* nextB;
}
class listB
{
nodeB* headB;
...
}
class nodeC
{
int data5;
double data6;
nodeC* nextC;
}
class listC
{
nodeC* headC;
...
}
What i'd like to know is how can i save the lists that i declare in my main so that if i close the program and then open it again i can recover the lists data
So lista_vendas::novaVenda needs to call lista_produto::escolheProduto.
To call lista_produto::escolheProduto you need a lista_produto object. Where are you going to get that lista_produto object from?
There's really only three ways this can be done. I don't know which way is the correct way for you, but I'll list them and you can decide.
1) Have a lista_produto global variable, a global list of products. Then lista_vendas::novaVenda can use the global lista_produto to call lista_produto::escolheProduto. This is the simple solution, but global variables are rightly considered bad style. It also means that you program can only have one list of products, is that a problem? Think carefully before trying this solution.
2) Have a lista_produto as a member variable of lista_vendas or no_vendas. I guessing here but perhaps something like this
class no_vendas
{
public:
unsigned int codigoVenda, dia, mes, ano, numeroItens;
double precoTotal;
lista_produto productList; // list of products
no_vendas* proxi; //referencia para o proximo no
};
Now each vendor has a list of products, which makes sense. So lista_vendas::novaVenda now has access to a lista_produto in each no_vendas and it can use that to call lista_produto::escolheProduto. If this makes sense then this is problably the best solution.
3) Pass a lista_produto as a parameter to lista_vendas::novaVenda. Like this
void novaVenda(unsigned int codigoVenda, lista_produto* productList);
So whatever code calls lista_vendas::novaVenda must also supply the lista_produto that it needs.
As I said I don't know which of these possibilities is correct, because I don't know what you are trying to do (and I don't speak Spanish). But this is a problem in the relationships between your different objects. It's up to you to design your classes so that they can access the different objects that they need to work.
You mentioned inheritance in your title, but this doesn't feel like the right thing to do in this case.
This won't help you with your concrete problem at hand but I think you should use standard containers like std::vector<>. Implementing your own linked list is a nice finger exercise but seldom really necessary. That said, you should use std::vector<no_produto> instead of lista_produto:
#include <vector>
std::vector<no_produto> my_lista_produto;
// fill the vector:
my_lista_produto.push_back(my_no_produto_1);
my_lista_produto.push_back(my_no_produto_2);
// ...
// retrieve one item:
const no_produto &p = my_lista_produto[1];
// clear all items:
my_lista_produto.clear();
A complete list of all available methods can be found here.
Concerning your question: The question title mentions inheritance but there isn't any inheritance used in your example. In order to derive class B from class A you have to write
class A {
public:
void func();
};
class B : public A {
public:
void gunc();
};
This means essentially, B can be treated as an A. B contains the content of A and exposes the public interface of A by itself. Thus we can write:
void B::gunc() {
func();
}
even though B never defines the method func(), it inherited the method from A. I suspect, that you didn't inherit your classes properly from each other.
In addition to my initial thoughts about writing you own linked lists, please consider also composition instead of inheritance. You can find more information about the topic at Wikipedia or on Stack Overflow.

An alternative to PIMPL Idiom when you'd like the interface to have all the memory

The purpose of the PIMPL idiom is to hide implementation, including methods, structures, and even sizes of structures. One downside is it uses the heap.
However, what if I didn't want to hide the size requirements of anything. I just wanted to hide methods, the formatting of the structure and the variable names. One way would be to allocate an array of bytes of the perfect size, have the implementation constantly cast that to whatever structure and use that. But manually find the size of the bytes to allocate for the object? And do casts all the time? Obviously not practical.
Is there an idiom or general way of handling this case that is advantageous to PIMPL or opaque pointers.
A rather different approach could be to rethink the nature of what your objects really represent. In traditional OOP it's customary to think of all objects as self-contained entities that have their own data and methods. Some of those methods will be private to the class because they're just required for that class's own housekeeping, and so these are the kind of thing you usually move the 'impl' of a Pimpl class.
In a recent project I've been favouring the Domain-Driven Design approach where one of the desirables is to separate the data from the logic that does things with it. The data classes then become little more than structs, and the complex logic that previously was hidden in the Pimpl now can go in a Service object that has no state of its own.
Consider a (rather contrived) example of a game loop:
class EnemySoldier : public GameObject
{
public:
// just implement the basic GameObject interface
void updateState();
void draw(Surface&);
private:
std::unique_ptr<EnemySoldierImp> m_Pimpl;
};
class EnemySolderImpl
{
public:
// 100 methods of complex AI logic
// that you don't want exposed to clients
private:
StateData m_StateData;
};
void runGame()
{
for (auto gameObject : allGameObjects) {
gameObject->updateState();
}
}
This could be restructured so that instead of the GameObjects managing their data and their program logic, we separate these two things out:
class EnemySoldierData
{
public:
// some getters may be allowed, all other data only
// modifiable by the Service class. No program logic in this class
private:
friend class EnemySoldierAIService;
StateData m_StateData;
};
class EnemySoldierAIService
{
public:
EnemySoldierAIService() {}
void updateState(Game& game) {
for (auto& enemySoldierData : game.getAllEnemySoldierData()) {
updateStateForSoldier(game, enemySoldierData);
}
}
// 100 methods of AI logic are now here
// no state variables
};
We now don't have any need for Pimpls or any hacky tricks with memory allocation. We can also use the game programming technique of getting better cache performance and reduced memory fragmentation by storing the global state in several flat vectors rather than needing an array of pointers-to-base-classes, eg:
class Game
{
public:
std::vector<EnemySoldierData> m_SoldierData;
std::vector<MissileData> m_MissileData;
...
}
I find that this general approach really simplifies a lot of program code:
There's less need for Pimpls
The program logic is all in one place
It's much easier to retain backwards compatibility or drop in alternate implementations by choosing between the V1 and V2 version of the Service class at runtime
Much less heap allocation
The information you are trying to hide is exactly the same information the compiler needs in order to calculate the size. Which is to say, no, there is no idiom for finding the size without knowing the number and data types of the non-static members, because it isn't even possible.
On the other hand, you can hide the existence of helper functions just fine. Simply declare a nested type (this gives the nested members access to the private members of the outer class) and define that type only inside your private implementation file, putting your helper logic in static member functions of the nested type. You'll have to pass a pointer to the object instance to operate on as a parameter, but then you can access all members.
Example:
class FlatAPI
{
void helperNeedsPublicAccess();
void helperNeedsFullAccess();
T data;
public:
void publicFunction();
};
becomes
class PublicAPI
{
struct helpers;
T data;
public:
void publicFunction();
};
and implementation code
#include <public.h>
static void helperNeedsPublicAccess(PublicAPI* pThis) { pThis->publicFunction(); }
struct PublicAPI::helpers
{
static void helperNeedsFullAccess(PublicAPI* pThis) { std::cout << pThis->data; }
};
void PublicAPI::publicFunction()
{
helpers::helperNeedsFullAccess(this);
}
So here's a possible alternative that doesn't have the downsides of constant casting but improves the memory layout to make it similar to if you hadn't used PIMPL at all.
I'm going to assume that you application isn't really using just one pimpl, but actually you are using the pimpl for many classes, so its like, the impl of the first pimpl holds pimpls for many children classes, and the impls of those hold pimpls to many third-tier classes etc.
(The kinds of objects I'm envisioning are like, all the managers, the schedulers, the various kinds of engines in your app. Most likely not all the actual data records, those are probably in a standard container owned by one of the managers. But all the objects that you generally only have a fixed number of in the course of the application.)
The first idea is, similar to how std::make_shared works, I want to allocate the main object right along-side the "helper" object so that I get the "fast" memory layout without breaking encapsulation. The way I do this is allocate a contiguous block of memory big enough for both, and use placement new, so that the pimpl is right next to the impl.
By itself, that's not really any improvement, because the pimpl is just the size of a pointer, and whoever owns the pimpl now needs a pointer to the pimpl since it's now heap allocated.
However, now we basically try to do this for all of the layers at once.
What is needed to actually make this work:
Each pimpl class needs to expose a static member function which is available at run time which indicates its size in bytes. If the corresponding impl is simple, this might just be return sizeof(my_impl). If the corresponding impl contains other pimpls, then this is return sizeof(my_impl) + child_pimpl1::size() + child_pimpl2::size() + ....
Each pimpl class needs a custom operator new or similar factory function that will allocate to a given block of memory of the appropriate size
The pimpl and its impl (minus the pimpl children you are handling recursively)
Each of the pimpl children in succession, using their corresponding operator new or similar function.
Now, at the beginning of your app, you make one gigantic heap allocation which holds the "root" manager object or whatever corresponding object. (If there isn't one then you would introduce one just for this purpose.) And you use its factory function there, allocating all of these objects contiguously.
I think this gives essentially the same benefits as if you made all the pimpls hold char[] of the exactly right size and constantly casted things. It will only work well though if you really only need a fixed number of these guys, or never too many. If you need to tear down and rebuild these objects often, that's okay, since you'll just manually call the destructors and use placement new to reconstruct. But you won't really be able to give any of the memory back until the end of the application, so there's some trade-off involved.
The purpose of the PIMPL idiom is to hide implementation, including
methods, structures, and even sizes of structures.
See also, http://herbsutter.com/gotw/_100/
One downside is it uses the heap.
I consider the use of the heap an upside. Stack is much more valuable and
much more limited (8Mbytes vs 3GBytes on my hw).
However, what if I didn't want to hide the size requirements of
anything.
My imagination has failed me many times. I will try to assume you know
what you want, and why you want it.
IMHO, failing to hide size info is of no consequence.
I just wanted to hide methods, and the formatting of the structure and
the variable names.
I think you still need to expose ctor and dtor
(or named alternatives i.e. createFoo/removeFoo )
One way would be to allocate an array of bytes of the perfect size,
this is easily done.
have the implementation constantly cast that to whatever structure and
use that.
IMHO no casting is required (I have never needed it - see MCVE below.)
But, even if you cast for some reason I can't guess at,
remember that casting (without conversion) causes no code,
and thus no performance issue.
But manually find the size of the bytes to allocate for the object?
Pragmatically this is only a minor challenge during development
(when the size might change). In my earlier career, I have
initially guessed for a dozen efforts, typically using a somewhat bigger than necessary data size estimate to accommodate growth.
I then add a run time assert (you might prefer to use "if clause")
to generate notices when the size is bigger than the goal. It has been my experience that the data size has always stabilized very quickly.
It is trivial to make the size info exact (if you want).
And do casts all the time? Obviously not practical.
I do not understand why you think casts are involved. I do not use
any in the pimples I create (nor in the MCVE below).
I do not understand why you (and at least 1 other) think casts are not
practical. non-conversion casts cost nothing (at runtime) and are
completely handled by the compiler. Maybe I will ask SO some related question someday. Even my editor can automate the cast prefix.
I do not understand why at least 1 comment thinks there are void
pointers to cast. I have used none.
Is there an idiom or general way of handling this case that is
advantageous to PIMPL or opaque pointers.
I know of no such idiom. I have found several examples that I think
conform to my expectations of handling pimpl, does that make them
general? Probably not.
Note, however, that from my many years in embedded systems work I
consider the below listed summarized ideas / requirements as relatively simple
challenges.
Feed back welcome.
Summary Requirements:
cancel size information hiding. Size info exposure is acceptable.
hide methods (exception: ctor and dtor or named ctor/dtor alternatives)
allocate array of bytes (implBuff) as location for pimple attribute.
manually provide pimple size info
provide output to cout the current impl size (to simplify development)
assert when manual size of implBuff is too small to hold actual impl
assert when manual size of implBuff is too wasteful of space
demonstrate why casting is not required
(hmmm, negative proofs are difficult.how about I simply show code with no casting needed)
Make note of pathological dependencies, show pragmatic solution if easy
NOTE:
These choices are sometimes not without 'pathological dependencies',
I have found 2, which I think are easily handled or ignored. See below.
The following MCVE builds and runs on my Ubuntu 15.04, g++ ver 4.9.2-10ubuntu13
An example output follows the code:
#include <iostream>
#include <sstream>
#include <vector>
#include <cassert>
// ///////////////////////////////////////////////////////////////////////
// ///////////////////////////////////////////////////////////////////////
// file Foo.hh
class Foo // a pimple example
{
public:
Foo();
~Foo();
// alternative for above two methods: use named ctor/dtor
// diagnostics only
std::string show();
// OTHER METHODS not desired
private:
// pathological dependency 1 - manual guess vs actual size
enum SizeGuessEnum { SizeGuess = 24048 };
char implBuff [SizeGuess]; // space inside Foo object to hold FooImpl
// NOTE - this is _not_ an allocation - it is _not_ new'd, so do not delete
// optional: declare the name of the class/struct to hold Foo attributes
// this is only a class declaration, with no implementation info
// and gives nothing away with its name
class FooImpl;
// USE RAW pointer only, DO NOT USE any form of unique_ptr
// because pi does _not_ point to a heap allocated buffer
FooImpl* pi; // pointer-to-implementation
};
// ///////////////////////////////////////////////////////////////////////
// ///////////////////////////////////////////////////////////////////////
// top of file Foo.cc
typedef std::vector<std::string> StringVec;
// the impl defined first
class Foo::FooImpl
{
private:
friend class Foo; // allow Foo full access
FooImpl() : m_indx(++M_indx)
{
std::cout << "\n Foo::FooImpl() sizeof() = "
<< sizeof(*this); // proof this is accessed
}
~FooImpl() { m_indx = 0; }
uint64_t m_indx; // unique id for this instance
StringVec m_stringVec[1000]; // room for 1000 strings
static uint64_t M_indx;
};
uint64_t Foo::FooImpl::M_indx = 0; // allocation of static
// Foo ctor
Foo::Foo(void) : pi (nullptr)
{
// pathological dependency 1 - manual guess vs actual size
{
// perform a one-time run-time VALIDATE of SizeGuess
// get the compiler's actual size
const size_t ActualSize = sizeof(FooImpl);
// SizeGuess must accomodate entire FooImpl
assert(SizeGuess >= ActualSize);
// tolerate some extra buffer - production code might combine above with below to make exact
// SizeGuess can be a little bit too big, but not more than 10 bytes too big
assert(SizeGuess <= (ActualSize+10));
}
// when get here, the implBuff has enough space to hold a complete Foo::FooImpl
// some might say that the following 'for loop' would cause undefined behavior
// by treating the code differently than subsequent usage
// I think it does not matter, so I will skip
{
// 0 out the implBuff
// for (int i=0; i<SizeGuess; ++i) implBuff[i] = 0;
}
// pathological dependency 2 - use of placement new
// --> DOES NOT allocate heap space (so do not deallocate in dtor)
pi = new (implBuff) FooImpl();
// NOTE: placement new does not allocate, it only runs the ctor at the address
// confirmed by cout of m_indx
}
Foo::~Foo(void)
{
// pathological dependency 2 - placement new DOES NOT allocate heap space
// DO NOT delete what pi points to
// YOU MAY perform here the actions you think are needed of the FooImpl dtor
// or
// YOU MAY write a FooImpl.dtor and directly invoke it (i.e. pi->~FooImpl() )
//
// BUT -- DO NOT delete pi, because FOO did not allocate *pi
}
std::string Foo::show() // for diagnostics only
{
// because foo is friend class, foo methods have direct access to impl
std::stringstream ss;
ss << "\nsizeof(FooImpl): " << sizeof(FooImpl)
<< "\n SizeGuess: " << SizeGuess
<< "\n this: " << (void*) this
<< "\n &implBuff: " << &implBuff
<< "\n pi->m_indx: " << pi->m_indx;
return (ss.str());
}
int t238(void) // called by main
{
{
Foo foo;
std::cout << "\n foo on stack: " << sizeof(foo) << " bytes";
std::cout << foo.show() << std::endl;
}
{
Foo* foo = new Foo;
std::cout << "\nfoo ptr to Heap: " << sizeof(foo) << " bytes";
std::cout << "\n foo in Heap: " << sizeof(*foo) << " bytes";
std::cout << foo->show() << std::endl;
delete foo;
}
return (0);
}
Example output:
// output
// Foo::FooImpl() sizeof() = 24008
// foo on stack: 24056 bytes
// sizeof(FooImpl): 24008
// SizeGuess: 24048
// this: 0x7fff269e37d0
// &implBuff: 0x7fff269e37d0
// pi->m_indx: 1
//
// Foo::FooImpl() sizeof() = 24008
// foo ptr to Heap: 8 bytes
// foo in Heap: 24056 bytes
// sizeof(FooImpl): 24008
// SizeGuess: 24048
// this: 0x1deffe0
// &implBuff: 0x1deffe0
// pi->m_indx: 2

Alternatives to an Object Pool?

I'm not quite sure that I need an object pool, yet it seems the most viable solution, but has some un-wanted cons associated with it. I am making a game, where entities are stored within an object pool. These entities are not allocated directly with new, instead a std::deque handles the memory for them.
This is what my object pool more or less looks like:
struct Pool
{
Pool()
: _pool(DEFAULT_SIZE)
{}
Entity* create()
{
if(!_destroyedEntitiesIndicies.empty())
{
_nextIndex = _destroyedEntitiesIndicies.front();
_destroyedEntitiesIndicies.pop();
}
Entity* entity = &_pool[_nextIndex];
entity->id = _nextIndex;
return entity;
}
void destroy(Entity* x)
{
_destroyedEntitiesIndicies.emplace(x->id);
x->id = 0;
}
private:
std::deque<Entity> _pool;
std::queue<int> _destroyedEntitiesIndicies;
int _nextIndex = 0;
};
If I destroy an entity, it's ID will be added to the _destroyedEntitiesIndicies queue, which will make it so that the ID will be re-used, and lastly it's ID will be set to 0. Now the only pitfall to this is, if I destroy an entity and then immediately create a new one, the Entity that was previously destroyed will be updated to be the same entity that was just created.
i.e.
Entity* object1 = pool.create(); // create an object
pool.destroy(object1); // destroy it
Entity* object2 = pool.create(); // create another object
// now object1 will be the same as object2
std::cout << (object1 == object2) << '\n'; // this will print out 1
This doesn't seem right to me. How do I avoid this? Obviously the above will probably not happen (as I'll delay object destruction until the next frame). But this may cause some disturbance whilst saving entity states to a file, or something along those lines.
EDIT:
Let's say I did NULL entities to destroy them. What if I was able to get an Entity from the pool, or store a copy of a pointer to the actual entity? How would I NULL all the other duplicate entities when destroyed?
i.e.
Pool pool;
Entity* entity = pool.create();
Entity* theSameEntity = pool.get(entity->getId());
pool.destroy(entity);
// now entity == nullptr, but theSameEntity still points to the original entity
If you want an Entity instance only to be reachable via create, you will have to hide the get function (which did not exist in your original code anyway :) ).
I think adding this kind of security to your game is quite a bit of an overkill but if you really need a mechanism to control access to certain parts in memory, I would consider returning something like a handle or a weak pointer instead of a raw pointer. This weak pointer would contain an index on a vector/map (that you store somewhere unreachable to anything but that weak pointer), which in turn contains the actual Entity pointer, and a small hash value indicating whether the weak pointer is still valid or not.
Here's a bit of code so you see what I mean:
struct WeakEntityPtr; // Forward declaration.
struct WeakRefIndex { unsigned int m_index; unsigned int m_hash; }; // Small helper struct.
class Entity {
friend struct WeakEntityPtr;
private:
static std::vector< Entity* > s_weakTable( 100 );
static std::vector< char > s_hashTable( 100 );
static WeakRefIndex findFreeWeakRefIndex(); // find next free index and change the hash value in the hashTable at that index
struct WeakEntityPtr {
private:
WeakRefIndex m_refIndex;
public:
inline Entity* get() {
Entity* result = nullptr;
// Check if the weak pointer is still valid by comparing the hash values.
if ( m_refIndex.m_hash == Entity::s_hashTable[ m_refIndex.m_index ] )
{
result = WeakReferenced< T >::s_weakTable[ m_refIndex.m_index ];
}
return result;
}
}
This is not a complete example though (you will have to take care of proper (copy) constructors, assignment operations etc etc...) but it should give you the idea what I am talking about.
However, I want to stress that I still think a simple pool is sufficient for what you are trying to do in that context. You will have to make the rest of your code to play nicely with the entities so they don't reuse objects that they're not supposed to reuse, but I think that is easier done and can be maintained more clearly than the whole handle/weak pointer story above.
This question seems to have various parts. Let's see:
(...) If I destroy an entity and then immediately create a new one,
the Entity that was previously destroyed will be updated to be the
same entity that was just created. This doesn't seem right to me. How
do I avoid this?
You could modify this method:
void destroy(Entity* x)
{
_destroyedEntitiesIndicies.emplace(x->id);
x->id = 0;
}
To be:
void destroy(Entity *&x)
{
_destroyedEntitiesIndicies.emplace(x->id);
x->id = 0;
x = NULL;
}
This way, you will avoid the specific problem you are experiencing. However, it won't solve the whole problem, you can always have copies which are not going to be updated to NULL.
Another way is yo use auto_ptr<> (in C++'98, unique_ptr<> in C++-11), which guarantee that their inner pointer will be set to NULL when released. If you combine this with the overloading of operators new and delete in your Entity class (see below), you can have a quite powerful mechanism. There are some variations, such as shared_ptr<>, in the new version of the standard, C++-11, which can be also useful to you. Your specific example:
auto_ptr<Entity> object1( new Entity ); // calls pool.create()
object1.release(); // calls pool.destroy, if needed
auto_ptr<Entity> object2( new Entity ); // create another object
// now object1 will NOT be the same as object2
std::cout << (object1.get() == object2.get()) << '\n'; // this will print out 0
You have various possible sources of information, such as the cplusplus.com, wikipedia, and a very interesting article from Herb Shutter.
Alternatives to an Object Pool?
Object pools are created in order to avoid continuous memory manipulation, which is expensive, in those situations in which the maximum number of objects is known. There are not alternatives to an object pool that I can think of for your case, I think you are trying the correct design. However, If you have a lot of creations and destructions, maybe the best approach is not an object pool. It is impossible to say without experimenting, and measuring times.
About the implementation, there are various options.
In the first place, it is not clear whether you're experiencing performance advantages by avoiding memory allocation, since you are using _destroyedEntitiesIndicies (you are anyway potentially allocating memory each time you destroy an object). You'll have to experiment with your code if this is giving you enough performance gain in contrast to plain allocation. You can try to remove _destroyedEntitiesIndicies altogether, and try to find an empty slot only when you are running out of them (_nextIndice >= DEFAULT_SIZE ). Another thing to try is discard the memory wasted in those free slots and allocate another chunk (DEFAULT_SIZE) instead.
Again, it all depends of the real use you are experiencing. The only way to find out is experimenting and measuring.
Finally, remember that you can modify class Entity in order to transparently support the object pool or not. A benefit of this is that you can experiment whether it is a really better approach or not.
class Entity {
public:
// more things...
void * operator new(size_t size)
{
return pool.create();
}
void operator delete(void * entity)
{
}
private:
Pool pool;
};
Hope this helps.

Factory method anti-if implementation

I'm applying the Factory design pattern in my C++ project, and below you can see how I am doing it. I try to improve my code by following the "anti-if" campaign, thus want to remove the if statements that I am having. Any idea how can I do it?
typedef std::map<std::string, Chip*> ChipList;
Chip* ChipFactory::createChip(const std::string& type) {
MCList::iterator existing = Chips.find(type);
if (existing != Chips.end()) {
return (existing->second);
}
if (type == "R500") {
return Chips[type] = new ChipR500();
}
if (type == "PIC32F42") {
return Chips[type] = new ChipPIC32F42();
}
if (type == "34HC22") {
return Chips[type] = new Chip34HC22();
}
return 0;
}
I would imagine creating a map, with string as the key, and the constructor (or something to create the object). After that, I can just get the constructor from the map using the type (type are strings) and create my object without any if. (I know I'm being a bit paranoid, but I want to know if it can be done or not.)
You are right, you should use a map from key to creation-function.
In your case it would be
typedef Chip* tCreationFunc();
std::map<std::string, tCreationFunc*> microcontrollers;
for each new chip-drived class ChipXXX add a static function:
static Chip* CreateInstance()
{
return new ChipXXX();
}
and also register this function into the map.
Your factory function should be somethink like this:
Chip* ChipFactory::createChip(std::string& type)
{
ChipList::iterator existing = microcontrollers.find(type);
if (existing != microcontrollers.end())
return existing->second();
return NULL;
}
Note that copy constructor is not needed, as in your example.
The point of the factory is not to get rid of the ifs, but to put them in a separate place of your real business logic code and not to pollute it. It is just a separation of concerns.
If you're desperate, you could write a jump table/clone() combo that would do this job with no if statements.
class Factory {
struct ChipFunctorBase {
virtual Chip* Create();
};
template<typename T> struct CreateChipFunctor : ChipFunctorBase {
Chip* Create() { return new T; }
};
std::unordered_map<std::string, std::unique_ptr<ChipFunctorBase>> jumptable;
Factory() {
jumptable["R500"] = new CreateChipFunctor<ChipR500>();
jumptable["PIC32F42"] = new CreateChipFunctor<ChipPIC32F42>();
jumptable["34HC22"] = new CreateChipFunctor<Chip34HC22>();
}
Chip* CreateNewChip(const std::string& type) {
if(jumptable[type].get())
return jumptable[type]->Create();
else
return null;
}
};
However, this kind of approach only becomes valuable when you have large numbers of different Chip types. For just a few, it's more useful just to write a couple of ifs.
Quick note: I've used std::unordered_map and std::unique_ptr, which may not be part of your STL, depending on how new your compiler is. Replace with std::map/boost::unordered_map, and std::/boost::shared_ptr.
No you cannot get rid of the ifs. the createChip method creats a new instance depending on constant (type name )you pass as argument.
but you may optimaze yuor code a little removing those 2 line out of if statment.
microcontrollers[type] = newController;
return microcontrollers[type];
To answer your question: Yes, you should make a factory with a map to functions that construct the objects you want. The objects constructed should supply and register that function with the factory themselves.
There is some reading on the subject in several other SO questions as well, so I'll let you read that instead of explaining it all here.
Generic factory in C++
Is there a way to instantiate objects from a string holding their class name?
You can have ifs in a factory - just don't have them littered throughout your code.
struct Chip{
};
struct ChipR500 : Chip{};
struct PIC32F42 : Chip{};
struct ChipCreator{
virtual Chip *make() = 0;
};
struct ChipR500Creator : ChipCreator{
Chip *make(){return new ChipR500();}
};
struct PIC32F42Creator : ChipCreator{
Chip *make(){return new PIC32F42();}
};
int main(){
ChipR500Creator m; // client code knows only the factory method interface, not the actuall concrete products
Chip *p = m.make();
}
What you are asking for, essentially, is called Virtual Construction, ie the ability the build an object whose type is only known at runtime.
Of course C++ doesn't allow constructors to be virtual, so this requires a bit of trickery. The common OO-approach is to use the Prototype pattern:
class Chip
{
public:
virtual Chip* clone() const = 0;
};
class ChipA: public Chip
{
public:
virtual ChipA* clone() const { return new ChipA(*this); }
};
And then instantiate a map of these prototypes and use it to build your objects (std::map<std::string,Chip*>). Typically, the map is instantiated as a singleton.
The other approach, as has been illustrated so far, is similar and consists in registering directly methods rather than an object. It might or might not be your personal preference, but it's generally slightly faster (not much, you just avoid a virtual dispatch) and the memory is easier to handle (you don't have to do delete on pointers to functions).
What you should pay attention however is the memory management aspect. You don't want to go leaking so make sure to use RAII idioms.