Is it supposed that const should be used for error detection or for documentation?

Suppose I have an immutable class C. From the user's point of view, we can never change the functional behavior of any object C.

However, for performance reasons, let's say we have a method toStringthat converts an object to a string and returns it. I don't want to do this calculation every time, so I save the result in a member variable, so if the user calls again toString, it will be fast.

I can make a toStringfunction const(and just use it const_castto save the result), since as long as we separate the interface from the implementation, toStringit should be considered as not changing the object, or should I make it not constant, because it will help to catch compiler errors?

+4
source share
3 answers

The point of existence of a const object is to ensure that it will not be changed during some procedure. This is completely due to the fact that you tell other developers your goal and provide the optimizer with information, since const does not exist at the level of machine code.

Const const, , const, , , const. const, , , const .

, , . , , , . , , const. , toString(), ( ). , , , , .

class ImmutableClass
{
private:
    std::string strTextRepresentation;

public:

    int nValue1, nValue2, nValue3; //variables that are to be used in the string

    ImmutableClass(int nValue1, int nValue2, int nValue3): 
        nValue1(nValue1), nValue2(nValue2), nValue3(nValue3)
    {
        std::stringstream ss;
        ss << nValue1 << ',' << nValue2 << ',' << nValue3;

        strTextRepresentation = ss.str();
    }

    const std::string& toString() const
    {
        return strTextRepresentation;
    }
};

, , , mutable. , " " . , , (, , , - toString()).

class ImmutableClass
{
private:
    mutable std::string strTextRepresentation;

public:

    int nValue1, nValue2, nValue3; //variables that are to be used in the string

    ImmutableClass(int nValue1, int nValue2, int nValue3): 
        nValue1(nValue1), nValue2(nValue2), nValue3(nValue3)
    {
    }

    const std::string& toString() const
    {
        //NOTE: consider using another kind of check for if the string
        //has been set. I recommend an optional<T> wrapper (easy to implement, or see the boost library)
        if (strTextRepresentation.size() == 0)
        {
            std::stringstream ss;
            ss << nValue1 << ',' << nValue2 << ',' << nValue3;

            strTextRepresentation = ss.str();
        }

        return strTextRepresentation;
    }
};

, , , , , . const_cast-ing , , , , , . const_cast , .

+2

Const , , . , , - .

-, , , ( ), . , .

, . , , mutable, ( , ) const-casted - undefined ( ). mutable, . ( , , std:: call_once... , )

const-cast mutable 7.1.6.1 5.2.11

, , mutable (7.1.1), , const (3.8) undefined.

const. , . clang: http://lists.llvm.org/pipermail/llvm-dev/2015-October/091178.html , . ( )

, :

  • , .
  • mutable const_cast.
+1

...

It is normal to have such a function. This approach is provided in the C ++ FAQ . The member function trailing const on inspect () should be used to mean that the method will not change abstract objects (the client is “visible” state. Just do not use const_cast, but mutable, see https://isocpp.org/wiki/faq / const-correctness # mutable-data-members .

0
source

All Articles