Question

I am trying to have a const operation on a class that is truly const - it does not change data that the class points to.

For example:

class Node{
public:
    int val;
};
class V{
public:
    Node * node; //what is the change that is needed here?
    void const_action()const{
        node->val=5; //error wanted here
    }
    void action(){
        node->val=5; //error is not wanted here
    }
};
Was it helpful?

Solution

You can use a template to enforce the const correctness on a pointer without changing the meaning or the implementation of your class:

    template <typename T>
class PreseveConstPointer
{
    T *t_;
public:
    PreseveConstPointer(T *t = nullptr)
        : t_(t)
    {
    }
    PreseveConstPointer<T> * operator=(T *t)
    {
        t_ = t;
        return this;
    }
    T* operator->()
    {
        return t_;
    }
    T const * operator->() const
    {
        return t_;
    }
    T * data()
    {
        return t_;
    }
};
class Node{
public:
    int val;
};
class V{
public:
    PreseveConstPointer<Node> node;
    V()
    {
        node = new Node;
    }
    ~V()
    {
        if(node.data())
            delete node.data();
    }
    void const_action()const{
        node->val=5; // You will get an error here
    }
    void action(){
        node->val=5; // No error here
    }
};

OTHER TIPS

const after a function declaration says that the function is not allowed to change any class members (except ones that are marked mutable).

Since your code doesn't change any class member, and only changes the object node points to, both function will compile.

AFAIK there's no way to prevent this. If you mark the node const, neither will compile.

You're confusing Node* const for Node const*.

An [unfortunate?] side effect of using indirection here is that constness of the pointer member has nothing to do with the actual Node on which you're operating.

If you don't need that member to be a pointer, then this is pleasingly easy:

class V
{
public:
    Node node;

    void const_action() const
    {
        node.val = 5; // error here
    }

    void action()
    {
        node.val = 5; // no error here
    }
};

However, given its name, I suspect life is not that simple and you are basically out of luck.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top