Quesiton with 'const'

Discussion in 'C++' started by yinglcs@gmail.com, Feb 13, 2006.

  1. Guest

    Hi,

    If I define a const stl vector attribute in my class,

    class A {
    public:
    A();
    private:
    const vector<int> v;
    };

    can I still add/remove elements to the list outside A's constructor?

    Thank you.
    , Feb 13, 2006
    #1
    1. Advertising

  2. wrote:
    > If I define a const stl vector attribute in my class,
    >
    > class A {
    > public:
    > A();
    > private:
    > const vector<int> v;
    > };
    >
    > can I still add/remove elements to the list outside A's constructor?


    No. What would be the point of declaring it 'const' if you could change
    it after construction?

    V
    --
    Please remove capital As from my address when replying by mail
    Victor Bazarov, Feb 13, 2006
    #2
    1. Advertising

  3. Gavin Deane Guest

    wrote:
    > Hi,
    >
    > If I define a const stl vector attribute in my class,
    >
    > class A {
    > public:
    > A();
    > private:
    > const vector<int> v;
    > };
    >
    > can I still add/remove elements to the list outside A's constructor?


    [Best not to describe a vector as a list, since a list is a different
    standard container]

    No. Neither can you add or remove elements _inside_ A's constructor.
    You can construct the vector is any way you choose in A's constructor's
    initialisation list, but then you can't change it. That's what const
    means. What did you think it meant in this context?

    Gavin Deane
    Gavin Deane, Feb 13, 2006
    #3
  4. Greg Guest

    Victor Bazarov wrote:
    > wrote:
    > > If I define a const stl vector attribute in my class,
    > >
    > > class A {
    > > public:
    > > A();
    > > private:
    > > const vector<int> v;
    > > };
    > >
    > > can I still add/remove elements to the list outside A's constructor?

    >
    > No. What would be the point of declaring it 'const' if you could change
    > it after construction?
    >
    > V


    The aim is probably to make "v" read-only in A's context, but
    read/writeable in some other context.

    Declaring the member vector const prevents anyone from modifying it.
    However a pointer to a const object need not point to a object declared
    const. So a member declaration of the form:

    const vector<int>* v;

    could point to a non-const std:vector<int>; all access to the vector
    through v though would have to treat the vector as const.

    Greg
    Greg, Feb 13, 2006
    #4
  5. mlimber Guest

    wrote:
    > Hi,
    >
    > If I define a const stl vector attribute in my class,
    >
    > class A {
    > public:
    > A();
    > private:
    > const vector<int> v;
    > };
    >
    > can I still add/remove elements to the list outside A's constructor?
    >
    > Thank you.


    No, as the others said, but using const and non-const member functions
    with a non-const vector may give you the behavior you want:

    class A
    {
    vector<int> v_;
    public:
    void Inspect() const // Note: const
    {
    v_.size(); // Ok: vector<>::size is also const
    v_.push_back( 42 ); // Error! v_ is const in this context
    }

    void Modify() // Note: non-const
    {
    v_.size(); // Ok
    v_.push_back( 42 ); // Ok
    }
    };

    Tell us what you are trying to do, and we may be able to help more.

    Cheers! --M
    mlimber, Feb 13, 2006
    #5
  6. Guest

    Thanks. I am looking for an emulation of Java's blank final attribute
    in C++.
    i.e. an attribute can not be changed after it is initialized in
    Constructor of the class.

    Thank you for all your ideas.
    , Feb 13, 2006
    #6
  7. Ben Pope Guest

    wrote:
    > Thanks. I am looking for an emulation of Java's blank final attribute
    > in C++.
    > i.e. an attribute can not be changed after it is initialized in
    > Constructor of the class.
    >
    > Thank you for all your ideas.


    Well a const member does that.

    class withConstMember {
    public:
    withConstMember(const int& i) : i_(i) {}
    private:
    const int i_;
    };

    int main()
    {
    withConstMember w(6);
    }



    The only problem is that you can't initialise an array in the
    initialiser list. Use std::vector<> instead.

    Ben Pope
    --
    I'm not just a number. To many, I'm known as a string...
    Ben Pope, Feb 13, 2006
    #7
  8. Ben Pope Guest

    Ben Pope wrote:
    > The only problem is that you can't initialise an array in the
    > initialiser list. Use std::vector<> instead.


    Example using vector:


    #include <vector>

    class withConstMember {
    public:
    withConstMember(const std::vector<int>& vec) : vec_(vec) {}
    private:
    const std::vector<int> vec_;
    };

    int main()
    {
    // create a vector with 4 elements with value 3
    std::vector<int> otherVector(4,3);

    withConstMember w(otherVector);
    }



    Ben Pope
    --
    I'm not just a number. To many, I'm known as a string...
    Ben Pope, Feb 13, 2006
    #8
  9. Andre Kostur Guest

    "Greg" <> wrote in news:1139862461.360862.267930
    @f14g2000cwb.googlegroups.com:

    >
    > Victor Bazarov wrote:
    >> wrote:
    >> > If I define a const stl vector attribute in my class,
    >> >
    >> > class A {
    >> > public:
    >> > A();
    >> > private:
    >> > const vector<int> v;
    >> > };
    >> >
    >> > can I still add/remove elements to the list outside A's constructor?

    >>
    >> No. What would be the point of declaring it 'const' if you could

    change
    >> it after construction?
    >>
    >> V

    >
    > The aim is probably to make "v" read-only in A's context, but
    > read/writeable in some other context.


    Huh? If A doesn't "control" v, why would v be a member?

    > Declaring the member vector const prevents anyone from modifying it.
    > However a pointer to a const object need not point to a object declared
    > const. So a member declaration of the form:
    >
    > const vector<int>* v;
    >
    > could point to a non-const std:vector<int>; all access to the vector
    > through v though would have to treat the vector as const.


    Yes.... but one in an object, and one is a pointer to an object. Much
    different semantics. BTW: You don't happen to be changing languages
    from Java to C++, are you?
    Andre Kostur, Feb 13, 2006
    #9
  10. mlimber Guest

    Ben Pope wrote:
    > Ben Pope wrote:
    > > The only problem is that you can't initialise an array in the
    > > initialiser list. Use std::vector<> instead.

    >
    > Example using vector:
    >
    >
    > #include <vector>
    >
    > class withConstMember {
    > public:
    > withConstMember(const std::vector<int>& vec) : vec_(vec) {}
    > private:
    > const std::vector<int> vec_;
    > };
    >
    > int main()
    > {
    > // create a vector with 4 elements with value 3
    > std::vector<int> otherVector(4,3);
    >
    > withConstMember w(otherVector);
    > }


    Or you could do something like this using method chaining (cf.
    http://www.parashift.com/c -faq-lite/ctors.html#faq-10.18):

    #include <vector>
    using namespace std;

    template<typename T>
    class Initializer
    {
    vector<T> v_;
    public:
    Initializer& Add( const T& t )
    {
    v_.push_back(t);
    return *this;
    }

    operator vector<T>() const { return v_; }
    };

    class A
    {
    public:
    A()
    : v_( Initializer<int>()
    .Add( 86 )
    .Add( 75 )
    .Add( 30 )
    .Add( 9 ) )
    {}

    private:
    const vector<int> v_;
    };

    Cheers! --M
    mlimber, Feb 13, 2006
    #10
  11. Guest

    Thanks. One question:
    what does this line do?
    operator vector<T>() const { return v_; }

    Why we need that in the Initializer class?
    , Feb 13, 2006
    #11
  12. Ben Pope Guest

    wrote:
    > Thanks. One question:
    > what does this line do?
    > operator vector<T>() const { return v_; }
    >
    > Why we need that in the Initializer class?


    It's a conversion to vector<T>, allowing that class to be used to
    construct the member vector in the initialiser list.

    Ben Pope
    --
    I'm not just a number. To many, I'm known as a string...
    Ben Pope, Feb 13, 2006
    #12
  13. Guest

    I have a different example , I wonder how can I use teh Initializer.

    class A
    {
    public :
    A(const B& b) ;
    private:
    const int x;
    const int y;
    void func1(B& b);
    void func2(B& b);
    }

    A::A(const B&b) {
    // this will not compile since this is not done in the initializer.
    x = func1(b);
    y = func2(b);
    }

    Is there a work around? of course, I can remove 'const' in x, y.
    But I wonder if there is a better solution.

    Thank you.
    , Feb 14, 2006
    #13
  14. Gavin Deane Guest

    wrote:

    > I have a different example , I wonder how can I use teh Initializer.
    >
    > class A
    > {
    > public :
    > A(const B& b) ;
    > private:
    > const int x;
    > const int y;
    > void func1(B& b);
    > void func2(B& b);
    > }


    Missing semicolon.

    > A::A(const B&b) {
    > // this will not compile since this is not done in the initializer.
    > x = func1(b);
    > y = func2(b);
    > }
    >
    > Is there a work around? of course, I can remove 'const' in x, y.
    > But I wonder if there is a better solution.


    Removing the const qualification from x and y won't work until you
    change func1 and func2 to return int instead of void and to take a
    const B& instead of a B&.

    After correcting those problems and simplifying the class, you need to
    understand the difference between initialisation and assignment.

    class B;

    class A
    {
    public :
    A(const B& b);
    private:
    const int x;
    int func1(const B& b);
    };

    Do you know what the difference is between this, which does not compile

    A::A(const B&b) {
    x = func1(b); // Does not compile.
    }

    and this, which does compile

    A::A(const B&b) : x(func1(b)) {} // Does compile.

    Gavin Deane
    Gavin Deane, Feb 14, 2006
    #14
  15. Ben Pope Guest

    wrote:
    > I have a different example , I wonder how can I use teh Initializer.
    >
    > class A
    > {
    > public :
    > A(const B& b) ;
    > private:
    > const int x;
    > const int y;
    > void func1(B& b);
    > void func2(B& b);
    > }
    >
    > A::A(const B&b) {
    > // this will not compile since this is not done in the initializer.
    > x = func1(b);
    > y = func2(b);
    > }
    >
    > Is there a work around? of course, I can remove 'const' in x, y.
    > But I wonder if there is a better solution.


    Well none of this will work.

    What do you want to achieve?

    func1 and func2 do not return a value, so you can't use the return value
    to initialise an int. Do func1 and func2 modify b? If not, use const,
    otherwise remove the const from constructor of A.

    Anyway, you can call a function in the initialiser list, consider:

    class B;

    class A {
    public :
    A(const B& b);
    private:
    const int x;
    const int y;
    int func1(const B& b);
    int func2(const B& b);
    };

    A::A(const B& b) : x(func1(b)), y(func2(b)) {
    }


    With appropriate missing pieces filled in, of course.

    Ben Pope
    --
    I'm not just a number. To many, I'm known as a string...
    Ben Pope, Feb 14, 2006
    #15
  16. Axter Guest

    Ben Pope wrote:
    > wrote:
    > > Thanks. I am looking for an emulation of Java's blank final attribute
    > > in C++.
    > > i.e. an attribute can not be changed after it is initialized in
    > > Constructor of the class.
    > >
    > > Thank you for all your ideas.

    >
    > Well a const member does that.
    >
    > class withConstMember {
    > public:
    > withConstMember(const int& i) : i_(i) {}
    > private:
    > const int i_;
    > };
    >
    > int main()
    > {
    > withConstMember w(6);
    > }
    >
    >
    >
    > The only problem is that you can't initialise an array in the
    > initialiser list. Use std::vector<> instead.


    Yes, you can. All you need is a method that returns that type.
    Example:
    class A {
    public:
    A():v(Init_v()) //Initialized list
    {
    }
    private:
    vector<int> Init_v()
    {
    vector<int> tmp;
    tmp.push_back(1);
    tmp.push_back(2);
    tmp.push_back(3);
    return tmp;
    }
    const vector<int> v;
    };

    Moreover, you can modify the above example so that the Init_v method
    takes argument(s) to assit in initializing the vector.
    Axter, Feb 14, 2006
    #16
  17. Ben Pope Guest

    Axter wrote:
    > Ben Pope wrote:
    >>
    >> The only problem is that you can't initialise an array in the
    >> initialiser list. Use std::vector<> instead.

    >
    > Yes, you can. All you need is a method that returns that type.


    <snip vector example>

    I'll repeat, "you can't initialise an array in the initialiser list.
    Use std::vector<> instead" [of an array].

    Ben Pope
    --
    I'm not just a number. To many, I'm known as a string...
    Ben Pope, Feb 14, 2006
    #17
    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:
    11
    Views:
    1,101
  2. Javier
    Replies:
    2
    Views:
    561
    James Kanze
    Sep 4, 2007
  3. 0m
    Replies:
    26
    Views:
    1,115
    Tim Rentsch
    Nov 10, 2008
  4. fungus
    Replies:
    13
    Views:
    887
    fungus
    Oct 31, 2008
  5. Replies:
    2
    Views:
    541
    Andrew Koenig
    Feb 9, 2009
Loading...

Share This Page