"Robert William Vesterman" <> wrote...
> I have a class that wants to keep track of all instances of itself.
> So, I'm currently doing something like this:
>
> class X
> {
> public:
> X ( int blah );
> const int blah();
> ~X();
>
> private:
> X();
> X ( const X& rhs );
> const X& operator= ( const X& rhs );
> static vector<X *> *xList;
I would use 'list' or 'set'. And there is no need to have it
as a pointer. Would eliminate the need to check it.
> int blah_;
> };
>
> The private constructors and the operator= are not defined, so the
> only way to make one is via the public constructor (right?).
>
> The xList pointer is initially zero.
>
> Whenever one of these is created, the constructor checks whether the
> xList pointer is still zero, and if so, initializes it to a new
> vector<X *>. It then pushes "this" onto xList..
If you don't declare it a pointer, there is no need to check,
just push.
>
> Whenever one is destroyed, the destructor finds "this" on xList, and
> erases it; if xList is then empty, it also does a delete on xList, and
> sets xList back to zero.
>
> So, my first question: Is there anything explicitly wrong with the
> above?
No.
>
> Second: If nothing's outright wrong with it, is there a better way to
> do it?
Use 'list' or 'set'. They are faster WRT insertions/deletions
than a 'vector'.
>
> Now, the next thing is that I want the outside world to be able to
> look at the list of existing x's - but not modify it. So, I defined a
> couple of public static functions:
>
> const vector<X *>::size_type getXCount();
> const X& getX ( vector<X *>::size_type index );
Both those members should probably be either static or const.
>
> If xList is zero, getXCount returns zero, else it returns
> xList->size(). getX gives a const reference to the X at the desired
> index (initializing xList first if it is zero) by using xList->at().
If you define it as 'list', the order is preserved (just like in
a vector, but getting one from a particular index could be slower.
With a 'set' the creation (insertion) order is not preserved, and
getting one from a particular index is slow too. So, pick the
collection based on your requirements.
> So it's going to throw some exception if an invalid index is
> specified.
>
> Third question: Anything wrong with that?
If the order is important, forget I suggested 'set'.
>
> Fourth question: Is there a better way?
Naming or keeping an ID could be the next step. Then you might
want to look at 'map' as your container.
>
> Really what I would like is to just let the outside world use standard
> vector stuff to look through the list, but I do not want them to be
> able to modify the list. So, for example, I would like them to be
> able to begin(), find(), operator++, and so forth, but not
> push_back(), erase(), and so forth. I could define all of these
> functions statically in my X class, but is there a less verbose way?
> Like (I don't know what I'm talking about here) a public function that
> returns a const reference to the vector, or something?
Sure, you could do that.
operator const vector<X*> () const { return xList; }
(again, I don't think there is a need to have 'xList' as a pointer)
Victor
|