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__