简体   繁体   中英

how to preserve const correctness across pointers?

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
    }
};

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
    }
};

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 const ness 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM