How to do this better?

Discussion in 'C++' started by Robert William Vesterman, Jun 26, 2003.

  1. 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.
    Robert William Vesterman, Jun 26, 2003
    #1
    1. Advertising

  2. "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
    Victor Bazarov, Jun 26, 2003
    #2
    1. Advertising

  3. On Wed, 25 Jun 2003 19:58:38 -0400, "Victor Bazarov"
    <> wrote:

    >"Robert William Vesterman" <> 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.
    Robert William Vesterman, Jun 26, 2003
    #3
  4. "Robert William Vesterman" <> wrote in message
    news:...
    > On Wed, 25 Jun 2003 19:58:38 -0400, "Victor Bazarov"
    > <> wrote:
    >
    > >"Robert William Vesterman" <> 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 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
    Victor Bazarov, Jun 26, 2003
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. dot_net_junky

    Which is better, C# or C++?

    dot_net_junky, Feb 9, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    435
    Tor B├ądshaug
    Feb 14, 2005
  2. Replies:
    0
    Views:
    379
  3. Peter Bencsik
    Replies:
    2
    Views:
    813
  4. Andrew Thompson
    Replies:
    8
    Views:
    135
    Premshree Pillai
    Jun 7, 2005
  5. Replies:
    2
    Views:
    44
    Mark H Harris
    May 13, 2014
Loading...

Share This Page