How to make the vector size unchanged but values not?

Discussion in 'C++' started by shuisheng, Sep 19, 2008.

  1. shuisheng

    shuisheng Guest

    Dear All,

    I have a question. Assume

    #include <vector>
    using namespace std;

    class A
    {
    private:
    vector<int> v;
    int n;

    public:
    void Reset(int i)
    {
    n = i;
    v.resize(i);
    }

    vector<int>& Vector()
    {
    return v;
    }
    };

    For class A, 'n' and the size of 'v' must be always consistent. Every
    time n is changed, v is reset with the size n. If n is not changed,
    the vector v's size can not change, but its values can change, such as

    A::Vector()[2] = 3;

    But user can use A::Vector().resize() to change the size of the
    vector. How can I avoid it and still keep all the std::vector 's
    functions to change the values?

    Thanks and best regards,

    Shuisheng
    shuisheng, Sep 19, 2008
    #1
    1. Advertising

  2. shuisheng

    Kai-Uwe Bux Guest

    shuisheng wrote:

    > Dear All,
    >
    > I have a question. Assume
    >
    > #include <vector>
    > using namespace std;
    >
    > class A
    > {
    > private:
    > vector<int> v;
    > int n;
    >
    > public:
    > void Reset(int i)
    > {
    > n = i;
    > v.resize(i);
    > }
    >
    > vector<int>& Vector()
    > {
    > return v;
    > }
    > };
    >
    > For class A, 'n' and the size of 'v' must be always consistent. Every
    > time n is changed, v is reset with the size n. If n is not changed,
    > the vector v's size can not change, but its values can change, such as
    >
    > A::Vector()[2] = 3;
    >
    > But user can use A::Vector().resize() to change the size of the
    > vector. How can I avoid it and still keep all the std::vector 's
    > functions to change the values?


    The easy way is to ditch the variable i. Since it cannot be observed from
    the outside, it does not make any sense to carry it around. Probably this
    possibility is due to oversimplification of the problem and does not arise
    in the original setting.

    The standard way would be to not expose the internal vector by means of a
    Vector() method but to narrow down its interface and make the needed
    functions available through forwarding. They would also update i.

    The hard way would be to not return a reference in the Vector() method, but
    a smart reference that updates i upon destruction. Since we cannot overload
    the dot-operator, there are some limitations to this method. We can,
    however, return a smart pointer.


    All in all, you seem to have a design problem that is best solved by
    avoiding the problem. What is the underlying conundrum that you are
    struggling with?


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Sep 19, 2008
    #2
    1. Advertising

  3. shuisheng

    shuisheng Guest

    On Sep 19, 10:34 am, Kai-Uwe Bux <> wrote:
    > shuisheng wrote:
    > > Dear All,

    >
    > > I have a question. Assume

    >
    > > #include <vector>
    > > using namespace std;

    >
    > > class A
    > > {
    > > private:
    > >   vector<int> v;
    > >   int n;

    >
    > > public:
    > >   void Reset(int i)
    > >   {
    > >     n = i;
    > >     v.resize(i);
    > >   }

    >
    > >   vector<int>& Vector()
    > >   {
    > >     return v;
    > >   }
    > > };

    >
    > > For class A, 'n' and the size of 'v' must be always consistent. Every
    > > time n is changed, v is reset with the size n. If n is not changed,
    > > the vector v's size can not change, but its values can change, such as

    >
    > > A::Vector()[2] = 3;

    >
    > > But user can use A::Vector().resize() to change the size of the
    > > vector. How can I avoid it and still keep all the std::vector 's
    > > functions to change the values?

    >
    > The easy way is to ditch the variable i. Since it cannot be observed from
    > the outside, it does not make any sense to carry it around.  Probably this
    > possibility is due to oversimplification of the problem and does not arise
    > in the original setting.
    >
    > The standard way would be to not expose the internal vector by means of a
    > Vector() method but to narrow down its interface and make the needed
    > functions available through forwarding. They would also update i.
    >
    > The hard way would be to not return a reference in the Vector() method, but
    > a smart reference that updates i upon destruction. Since we cannot overload
    > the dot-operator, there are some limitations to this method. We can,
    > however, return a smart pointer.
    >
    > All in all, you seem to have a design problem that is best solved by
    > avoiding the problem. What is the underlying conundrum that you are
    > struggling with?
    >
    > Best
    >
    > Kai-Uwe Bux


    The underlying problem is like that: I have a 2-D (two dimensional)
    field (or array), the field points are arranged regularly along x and
    y axis, which looks like a grid as follows,

    y2 . . . .
    y1 . . . .
    y0 . . . .
    x0 x1 x2 x3

    where the dots denote field points. Given two vectors: xv and yv, the
    grid points will be well defined. And the 2-D field have a size of
    (size of xv) by (size of yv). So every time reset xv and yv, the size
    of 2-D field will changed. But if the xv and yv do not change, only
    the field values can change. For 2-D filed/array, I use blitz::array,
    which is similar to std::vector but is 2-D.

    Thank you for your help!
    shuisheng, Sep 19, 2008
    #3
  4. shuisheng

    Kai-Uwe Bux Guest

    shuisheng wrote:

    > On Sep 19, 10:34 am, Kai-Uwe Bux <> wrote:
    >> shuisheng wrote:
    >> > Dear All,

    >>
    >> > I have a question. Assume

    >>
    >> > #include <vector>
    >> > using namespace std;

    >>
    >> > class A
    >> > {
    >> > private:
    >> > vector<int> v;
    >> > int n;

    >>
    >> > public:
    >> > void Reset(int i)
    >> > {
    >> > n = i;
    >> > v.resize(i);
    >> > }

    >>
    >> > vector<int>& Vector()
    >> > {
    >> > return v;
    >> > }
    >> > };

    >>
    >> > For class A, 'n' and the size of 'v' must be always consistent. Every
    >> > time n is changed, v is reset with the size n. If n is not changed,
    >> > the vector v's size can not change, but its values can change, such as

    >>
    >> > A::Vector()[2] = 3;

    >>
    >> > But user can use A::Vector().resize() to change the size of the
    >> > vector. How can I avoid it and still keep all the std::vector 's
    >> > functions to change the values?

    >>
    >> The easy way is to ditch the variable i. Since it cannot be observed from
    >> the outside, it does not make any sense to carry it around.  Probably
    >> this possibility is due to oversimplification of the problem and does not
    >> arise in the original setting.
    >>
    >> The standard way would be to not expose the internal vector by means of a
    >> Vector() method but to narrow down its interface and make the needed
    >> functions available through forwarding. They would also update i.
    >>
    >> The hard way would be to not return a reference in the Vector() method,
    >> but a smart reference that updates i upon destruction. Since we cannot
    >> overload the dot-operator, there are some limitations to this method. We
    >> can, however, return a smart pointer.
    >>
    >> All in all, you seem to have a design problem that is best solved by
    >> avoiding the problem. What is the underlying conundrum that you are
    >> struggling with?
    >>
    >> Best
    >>
    >> Kai-Uwe Bux

    >
    > The underlying problem is like that: I have a 2-D (two dimensional)
    > field (or array), the field points are arranged regularly along x and
    > y axis, which looks like a grid as follows,
    >
    > y2 . . . .
    > y1 . . . .
    > y0 . . . .
    > x0 x1 x2 x3
    >
    > where the dots denote field points. Given two vectors: xv and yv, the
    > grid points will be well defined. And the 2-D field have a size of
    > (size of xv) by (size of yv). So every time reset xv and yv, the size
    > of 2-D field will changed. But if the xv and yv do not change, only
    > the field values can change. For 2-D filed/array, I use blitz::array,
    > which is similar to std::vector but is 2-D.


    Hm, the least invasive I can think of, is to split the setter/getter
    function in two:

    vector< int > const & get_x ( void ) const {
    return xy;
    }

    void set_x ( vector< int > const & val ) {
    xy = val;
    // do whatever is needed to update the 2d-array
    }

    // similarly for y.

    However, getter and setter methods still smell NotSoGood(tm). The preferred
    way of going about this is to make the vectors and the 2d-array strictly
    private members of the class and to devise an interface that describes how
    an object of that type responds to messages. That way, proper encapsulation
    is ensured. That, however, will require a good deal of knowledge about the
    application domain where this class will be used.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Sep 19, 2008
    #4
  5. shuisheng

    maverik Guest

    On Sep 19, 6:55 pm, shuisheng <> wrote:
    > On Sep 19, 10:34 am, Kai-Uwe Bux <> wrote:


    [...]

    For 2-D filed/array, I use blitz::array,
    > which is similar to std::vector but is 2-D.


    You can use splices for emulating 2D arrays.
    maverik, Sep 20, 2008
    #5
    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. Replies:
    8
    Views:
    1,873
    Csaba
    Feb 18, 2006
  2. Markus Pitha

    Reference, but object unchanged?

    Markus Pitha, Oct 26, 2007, in forum: C++
    Replies:
    9
    Views:
    323
    James Kanze
    Oct 29, 2007
  3. zr
    Replies:
    18
    Views:
    1,997
    James Kanze
    Mar 28, 2009
  4. Paolo Zaffino
    Replies:
    7
    Views:
    7,111
    Prasad, Ramit
    Oct 19, 2011
  5. Thomas
    Replies:
    7
    Views:
    293
    Mark Hubbart
    May 23, 2005
Loading...

Share This Page