Tarique <pe*****@yahoo.comwrites:

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<floatv(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<floatv(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__