Logical Constness

Discussion in 'C++' started by Tarique, Jun 25, 2008.

  1. Tarique

    Tarique Guest

    Can someone please explain the idea of Logical Constness as explained in
    section 10.2.7.1 Of Stroustrup's "The C++ Programming Language" ,with a
    short working code if possible.

    Thank You
    Tarique, Jun 25, 2008
    #1
    1. Advertising

  2. Tarique

    SeanW Guest

    On Jun 25, 2:40 pm, Tarique <> wrote:
    > Can someone please explain the idea of Logical Constness as explained in
    > section 10.2.7.1 Of Stroustrup's "The C++ Programming Language" ,with a
    > short working code if possible.
    >
    > Thank You


    This article covers it: http://www.ddj.com/cpp/184403892

    Sean
    SeanW, Jun 25, 2008
    #2
    1. Advertising

  3. Tarique

    Tarique Guest

    SeanW wrote:
    > On Jun 25, 2:40 pm, Tarique <> wrote:
    >> Can someone please explain the idea of Logical Constness as explained in
    >> section 10.2.7.1 Of Stroustrup's "The C++ Programming Language" ,with a
    >> short working code if possible.
    >>
    >> Thank You

    >
    > This article covers it: http://www.ddj.com/cpp/184403892
    >
    > Sean


    I found this link when i Google'd it and i could not make much sense of
    it! Phew!!! I am only a C++ newbie. Maybe i should have mentioned that
    in my original post.

    I am only looking for a very short explanation if possible!

    Thanks again.
    Tarique, Jun 26, 2008
    #3
  4. Tarique <> writes:

    > Can someone please explain the idea of Logical Constness as explained
    > in section 10.2.7.1 Of Stroustrup's "The C++ Programming Language"
    > ,with a short working code if possible.


    Assume you have an object that has a very big vector of integers, and
    that provides a method to get the sum the integers in this very
    vector. Since computing this sum doesn't change the vector nor the
    sum, it's a method that is logicall const. But if you try to declare
    it formally const, then you cannot do the obvious optimization of
    caching this sum (or you need to declare mutable the sum and the flag
    that indicate that it's up-to-date).


    class Strange {
    protected:
    std::vector<float> v(1000000);
    public:
    float getSum(void) const;
    void set(int index,float value);
    };

    void Strange::set(int index,float value){
    v[index]=value;
    }

    float Strange::getSum(void) const {
    struct Summer{
    float sum;
    Summer():sum(0.0){}
    void sum(float incr){ sum+=incr; }
    };
    Summer s();
    for_each(v.begin(),v.end(),s); // very slow
    return(s.sum);
    }


    So instead, we could lose the const, and while the method getSum is
    still logically const, it can modify the object:


    class Strange {
    protected:
    std::vector<float> v(1000000);
    bool changed;
    float sumCache;
    public:
    Strange():changed(true){}
    float getSum(void) /* logically const */;
    void set(int index,float value);
    };

    void Strange::set(int index,float value){
    v[index]=value;
    changed=true;
    }

    float Strange::getSum(void) /* logically const */ {
    if(changed){
    struct Summer{
    float sum;
    Summer():sum(0.0){}
    void sum(float incr){ sum+=incr; }
    };
    Summer s();
    for_each(v.begin(),v.end(),s); // very slow
    sumCache=s.sum;
    }
    return(sumCache);
    }



    Another example:

    For a class of rationals, the normalization method doesn't change the
    value of the rationnal (4/8 == 1/2) so it is "logically const", while
    it still changes the numerator and denominator.

    --
    __Pascal Bourguignon__
    Pascal J. Bourguignon, Jun 26, 2008
    #4
  5. On 2008-06-26 08:25:33, Tarique wrote:

    > SeanW wrote:
    >> On Jun 25, 2:40 pm, Tarique <> wrote:
    >>> Can someone please explain the idea of Logical Constness as explained in
    >>> section 10.2.7.1 Of Stroustrup's "The C++ Programming Language" ,with a
    >>> short working code if possible.
    >>>
    >>> Thank You

    >>
    >> This article covers it: http://www.ddj.com/cpp/184403892
    >>
    >> Sean

    >
    > I found this link when i Google'd it and i could not make much sense of
    > it! Phew!!! I am only a C++ newbie. Maybe i should have mentioned that
    > in my original post.
    >
    > I am only looking for a very short explanation if possible!


    Logical constness means that an object appears as constant and works as if
    it were constant, but in reality some of the internal states do change.

    Gerhard
    Gerhard Fiedler, Jun 26, 2008
    #5
  6. Tarique

    Tarique Guest

    Pascal J. Bourguignon wrote:
    > Tarique <> writes:
    >
    >> Can someone please explain the idea of Logical Constness as explained
    >> in section 10.2.7.1 Of Stroustrup's "The C++ Programming Language"
    >> ,with a short working code if possible.

    >
    > Assume you have an object that has a very big vector of integers, and
    > that provides a method to get the sum the integers in this very
    > vector. Since computing this sum doesn't change the vector nor the
    > sum, it's a method that is logicall const. But if you try to declare
    > it formally const, then you cannot do the obvious optimization of
    > caching this sum (or you need to declare mutable the sum and the flag
    > that indicate that it's up-to-date).
    >


    _snip_


    >
    > Another example:
    >
    > For a class of rationals, the normalization method doesn't change the
    > value of the rationnal (4/8 == 1/2) so it is "logically const", while
    > it still changes the numerator and denominator.


    Thank You Sir.That really helped.
    Tarique, Jun 26, 2008
    #6
  7. Tarique

    James Kanze Guest

    On Jun 26, 1:25 pm, Tarique <> wrote:
    > SeanW wrote:
    > > On Jun 25, 2:40 pm, Tarique <> wrote:
    > >> Can someone please explain the idea of Logical Constness as
    > >> explained in section 10.2.7.1 Of Stroustrup's "The C++
    > >> Programming Language" ,with a short working code if
    > >> possible.


    > > This article covers it:http://www.ddj.com/cpp/184403892


    > I found this link when i Google'd it and i could not make much
    > sense of it! Phew!!! I am only a C++ newbie. Maybe i should
    > have mentioned that in my original post.


    > I am only looking for a very short explanation if possible!


    Logical const is generally opposed to bitwise const. Bitwise
    const is what the compiler implements (because it doesn't
    understand program logic). Logical const is what you, the
    programmer decide. (Back in the days before there was a
    consensus for logical const, it was sometimes known as
    Humpty-Dumpty const---see "Through the Looking Glass" for
    details.)

    Basically, with logical const, when you design a class, you
    decide what its value consists of; a const function will never
    modify that value. If that value includes additional objects,
    which are included indirectly, then you will not modify those
    objects through a const function, even if the compiler allows
    it. And if that value doesn't include some immediate members
    (the classical example is cached data), then you may modify
    those members in a const function (either by declaring them
    mutable, or by using const_cast). The important thing is that
    after calling a const function, client code will see the object
    with the same value as it had before the function, for whatever
    definition of value you have decided on for the class.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jun 27, 2008
    #7
  8. Tarique

    James Kanze Guest

    On Jun 26, 2:18 pm, (Pascal J. Bourguignon)
    wrote:
    > Tarique <> writes:
    > > Can someone please explain the idea of Logical Constness as explained
    > > in section 10.2.7.1 Of Stroustrup's "The C++ Programming Language"
    > > ,with a short working code if possible.


    > Assume you have an object that has a very big vector of
    > integers, and that provides a method to get the sum the
    > integers in this very vector. Since computing this sum
    > doesn't change the vector nor the sum, it's a method that is
    > logicall const. But if you try to declare it formally const,
    > then you cannot do the obvious optimization of caching this
    > sum (or you need to declare mutable the sum and the flag that
    > indicate that it's up-to-date).


    Unless you declare the cached value mutable, or use const_cast.

    The more frequent use of logical const is the reverse case:
    suppose you implement the vector using new and delete (rather
    than vector). Your class then contains an
    int* v ;
    As far as the compiler is concerned, you can modify elements in
    the vector even if the function is const, since the pointer
    remains a pointer to a non-const. If you implement logical
    const, however, you will not do so; any function which modifies
    elements in the vector will be non-const. (But you've chosen a
    good example. Modified as above, it can be used to show both
    sides of the issue.)

    By the way: the reason your example couldn't show this second
    aspect using std::vector is because std::vector implements
    logical const---internally, it contains a T*, and the compiler
    would allow something like: T& vector<T>::eek:perator[]( size_t )
    const. This example, in fact, brings out a third issue of
    logical const: if logical const is used, a const function will
    not "leak" non-const references or pointers to anything which is
    part of its value. Thus, the const version of
    vector<>::eek:perator[] returns a T const&, and not a T&.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jun 27, 2008
    #8
  9. Tarique

    Tarique Guest

    Tarique wrote:
    > Can someone please explain the idea of Logical Constness as explained in
    > section 10.2.7.1 Of Stroustrup's "The C++ Programming Language" ,with a
    > short working code if possible.
    >
    > Thank You
    > From - Thu


    I have tried implementing the example given in the same section (Naive
    though and only to test the idea!)

    #include<iostream>
    #include<string>
    using namespace std;

    class Date {
    int d,m,y;
    bool cache_valid;
    string cache;
    void compute_cache_value();//fill cache
    //..
    public:
    Date(int dd = 0,int mm = 0,int yy = 0); // Default constructor
    static Date default_date;
    ~Date(){}; // Destructor

    string string_rep()const;//string representation
    Date& add_day (int n);
    };

    Date Date::default_date(03,01,2000);
    Date::Date(int dd,int mm,int yy)
    {
    cache_valid = false;
    d = dd ? dd : default_date.d;
    m = mm ? mm : default_date.m;
    y = yy ? yy : default_date.y;

    }


    void Date::compute_cache_value()
    {
    switch(d) //Test_Only
    {
    case 1:case 8:case 15:case 22:case 29:cache = "Monday"; break;
    case 2:case 9:case 16:case 23:case 30:cache = "Tuesday"; break;
    case 3:case 10:case 17:case 24:case 31:cache = Wednesday";break;
    case 4:case 11:case 18:case 25:cache = "Thursday"; break;
    case 5:case 12:case 19:case 26:cache = "Friday"; break;
    case 6:case 13:case 20:case 27:cache = "Saturday"; break;
    case 7:case 14:case 21:case 28:cache = "Sunday"; break;
    }
    }

    string Date::string_rep() const
    {
    if(cache_valid == false) {
    Date* th = const_cast<Date*>(this);//Cast away const
    th->compute_cache_value();
    th->cache_valid = true;
    }
    return cache;
    }

    /*
    According to Stroustrups "The C++ Programming Language",
    the const_cast operator is _not guaranteed to work_ when applied to an
    object that was originally declared as const.
    Why is it so ?
    */

    Date& Date::add_day (int n) { //Without any bounds check!
    d+=n; //I assume d remains < 31
    cache_valid = false;
    return *this;
    }

    int main()
    {
    Date d1;
    const Date d2;
    string s1=d1.string_rep();
    cout<<s1<<endl;

    d1.add_day(2);
    cout<<d1.string_rep()<<endl;

    string s2=d2.string_rep(); //Undefined Behaviour .Why ?
    cout<<s2<<endl;
    return 0;
    }
    Tarique, Jun 29, 2008
    #9
    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. Martin Magnusson

    Casting away constness

    Martin Magnusson, Nov 17, 2003, in forum: C++
    Replies:
    1
    Views:
    370
    tom_usenet
    Nov 17, 2003
  2. Richard Hayden
    Replies:
    1
    Views:
    728
    Rob Williscroft
    Nov 23, 2003
  3. Trevor Lango

    Casting Away Constness

    Trevor Lango, Jan 2, 2004, in forum: C++
    Replies:
    15
    Views:
    2,377
    Ron Natalie
    Jan 2, 2004
  4. Marc
    Replies:
    6
    Views:
    669
    Denis Remezov
    Jul 6, 2004
  5. Replies:
    14
    Views:
    806
    Ian Collins
    Apr 4, 2006
Loading...

Share This Page