tags:

views:

54

answers:

3
class Base
{
public:
Base (int a, int b);
private:
int a,b;
};

class Derived1
{
public:
Derived1():base(1,2){}
};

similarly Derived2, Derived 3 which doesnt contain any data members on its own

Now i need to contain these derived objects in a singleton, so i was thinking to call this in base constructor like

Base::Base(int a, int b)
{
CBaseMgr::GetInstance()->AddtoVector(this);
}

so now if i construct

Derived d1, d2, d3 etc. will the Singleton's container contain all derived objects?

My doubt is can i do this adding of objects to container in base ctor or should i do in derived ctor.?

+1  A: 

If all the derived class call this base class constructor, yes, you should be fine.

Just beware of the copy constructor which, if not overloaded, will not add this to your global vector.

I suppose you want as well remove the instances that were destroyed, from the global vector ?

If so, don't forget to declare Base::~Base to be virtual, so that he gets called by derived classes.

ereOn
Removing the this instances in Base dtor, In this case i think the container has to be a map, since in vector how do i remove that "particular derived object". So if in a map, if i use say" description" data member as the key, will it still be valid in base dtor. I mean, when does the data members get deallocated in dtor, at the end of dtor's {}?
+1 for mentioning that all constructors need to be overloaded.
Matthieu M.
@vivekeviv: you don't need a map, you can certainly call `std::find` with a value (in case an instance of `Base*`). However, you should consider using a `set` or `unordered_set` if you plan on having a good number of elements at a given point in time (say ~1000).
Matthieu M.
@vivekeviv: As Matthieu M. said, using a `map` here is not needed. Remember that you just have a `vector` of pointers (a "number" if you want). Each instance will have it's own and unique "number" that will **never** change during its life-time. So yes, you can just remove it from the vector as you would do it with an integer value. Just beware that once an instance has been destroyed, another **might** reuse its address (aka. "number") again. So be sure to *always* remove them on destruction.
ereOn
A: 

Doing this in Base's constructor should be fine, as long as you're not dereferencing this before the whole construction is done.

KennyTM
A: 

My doubt is can i do this adding of objects to container in base ctor or should i do in derived ctor.?

You can safely do it in the base constructor but you have to take care of the following:

  • explicitely declare copy constructor semantics (if you want objects to be copy-constructible, fine; if not, declare the base copy constructor as private, and do not implement it, or make Base inherit privately from boost::noncopiable).

  • store Base references as pointers (I guess you already know this).

  • declare base's destructors virtual (and have them remove the instance from the manager)

  • make sure the removal process doesn't throw any exceptions ( throwing exceptions in destruction may lead to transforming the Earth into a singularity or other undefined behaviour :) ).

utnapistim
You have typo: it should be `boost::noncopyable`
ereOn
@utnapistim pl check my comment on ereOn reply. Thanks for the help
The order of destruction is the following: if you have `class derived: public base { int i; };`, first `derived::~derived` gets executed, then `i` becomes unavailable (if it has a non-pod type it's destructor gets called), then base::~base gets called, then all the destructors of the members of base.In your case, if the description is a member of base, it is safe to remove the base* from a map in the destructor, and to have the base* stored by a description held in base.
utnapistim