Pergunta

Estou tentando ter uma operação const em uma classe que seja verdadeiramente const - ela não altera os dados para os quais a classe aponta.

Por exemplo:

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
    }
};
Foi útil?

Solução

Você pode usar um modelo para impor a correção const em um ponteiro sem alterar o significado ou a implementação da sua classe:

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

Outras dicas

const após uma declaração de função diz que a função não tem permissão para alterar nenhum membro da classe (exceto aqueles que estão marcados mutable).

Como seu código não altera nenhum membro da classe e apenas altera o objeto node aponta para, ambas as funções serão compiladas.

AFAIK, não há como evitar isso.Se você marcar o node const, nenhum dos dois será compilado.

Você está confuso Node* const para Node const*.

Um efeito colateral [infeliz?] do uso indireto aqui é que constA qualidade do membro ponteiro não tem nada a ver com o real Node em que você está operando.

Se você não precisa que esse membro seja um indicador, isso é agradavelmente fácil:

class V
{
public:
    Node node;

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

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

No entanto, dado o seu nome, suspeito que a vida não seja tão simples e que você esteja basicamente sem sorte.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top