포인터 전체에서 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
}
};
해결책
템플릿을 사용하여 클래스의 의미 또는 구현을 변경하지 않고 포인터의 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
포인터 멤버의 ness는 실제 멤버와 아무 관련이 없습니다. Node
당신이 운영하고 있는 곳.
해당 멤버가 포인터가 될 필요가 없다면 이는 매우 쉽습니다.
class V
{
public:
Node node;
void const_action() const
{
node.val = 5; // error here
}
void action()
{
node.val = 5; // no error here
}
};
그러나 그 이름을 보면 인생은 그렇게 단순하지 않고 기본적으로 운이 좋지 않은 것 같습니다.
제휴하지 않습니다 StackOverflow