como preservar a correção const entre ponteiros?
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
}
};
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 const
A 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.