Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   How to do this better? (http://www.velocityreviews.com/forums/t267735-how-to-do-this-better.html)

Robert William Vesterman 06-25-2003 11:39 PM

How to do this better?
 
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;
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..

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?

Second: If nothing's outright wrong with it, is there a better way to
do it?

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 );

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().
So it's going to throw some exception if an invalid index is
specified.

Third question: Anything wrong with that?

Fourth question: Is there a better way?

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?

Thanks in advance for any help.

Bob Vesterman.

Victor Bazarov 06-25-2003 11:58 PM

Re: How to do this better?
 
"Robert William Vesterman" <bob@vesterman.com> 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



Robert William Vesterman 06-26-2003 04:43 AM

Re: How to do this better?
 
On Wed, 25 Jun 2003 19:58:38 -0400, "Victor Bazarov"
<v.Abazarov@attAbi.com> wrote:

>"Robert William Vesterman" <bob@vesterman.com> wrote...
>>
>> 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; }


I am confused by this syntax. Could you please show how a client
class would use this to get the xList from X?

Also, am I correct in the following? The reason why the above would
not allow them to do (for example) a push_back() is because the vector
they're given is const, and push_back() is not a const function, and
is therefore not allowed on const objects?

Thanks,

Bob Vesterman.

Victor Bazarov 06-26-2003 01:21 PM

Re: How to do this better?
 
"Robert William Vesterman" <bob@vesterman.com> wrote in message
news:55ukfvcmgdgh900krfdthokkjfcm7u4fbp@4ax.com...
> On Wed, 25 Jun 2003 19:58:38 -0400, "Victor Bazarov"
> <v.Abazarov@attAbi.com> wrote:
>
> >"Robert William Vesterman" <bob@vesterman.com> wrote...
> >>
> >> 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; }

>
> I am confused by this syntax. Could you please show how a client
> class would use this to get the xList from X?
>
> Also, am I correct in the following? The reason why the above would
> not allow them to do (for example) a push_back() is because the vector
> they're given is const, and push_back() is not a const function, and
> is therefore not allowed on const objects?


First, let me say that I made a mistake. I intended to write

operator const vector<X*>& () const { return xList; }

because there is no need to copy the stuff, returning a reference
should be satisfactory.

As to how to use it, this should be an illustration:

const vector<X*>& v(yourClassInstance);

and then do what they want, like accessing v[i] or v.begin()
or whatever. And yes, you're correct, since the vector is const
they won't be able to modify it directly (without a const_cast).

Victor




All times are GMT. The time now is 08:28 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.