如何跨指针保持const正确性?

时间:2014-01-11 17:21:18

标签: c++ const

我试图对一个真正const的类进行const操作 - 它不会改变该类所指向的数据。

例如:

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

3 个答案:

答案 0 :(得分:4)

您可以使用模板在指针上强制执行const正确性,而无需更改类的含义或实现:

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

答案 1 :(得分:1)

函数声明后

const表示不允许该函数更改任何类成员(标记为mutable的成员除外)。

由于您的代码不会更改任何类成员,并且仅更改对象node指向,因此两个函数都将编译。

AFAIK没有办法阻止这一点。如果您标记node const,则不会编译。

答案 2 :(得分:1)

您对Node* const Node const*感到困惑。

这里使用间接的[不幸?]副作用是指针成员的const与你正在操作的实际Node无关。

如果你不需要那个成员作为指针,那么这很容易:

class V
{
public:
    Node node;

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

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

然而,鉴于它的名字,我怀疑生活并不那么简单,你基本上没有运气。