как сохранить константную корректность во всех указателях?
Вопрос
Я пытаюсь выполнить операцию 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
}
};
Решение
Вы можете использовать шаблон для обеспечения того, чтобы обеспечить правильность корректности 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
}
};
. Другие советы
const
после объявления функции говорится, что функции не разрешается изменять какие-либо члены класса (кроме тех, которые помечены mutable
).
Поскольку ваш код не изменяет ни одного члена класса, а изменяет только объект node
указывает на то, что обе функции будут скомпилированы.
AFAIK, нет никакого способа предотвратить это.Если вы отметите node
const
, ни один из них не будет компилироваться.
Ты сбиваешь с толку 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
}
};
Однако, учитывая его название, я подозреваю, что жизнь не так проста, и вам, по сути, не повезло.