ポインター間で 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
を指すと、両方の関数がコンパイルされます。
私の知る限り、これを防ぐ方法はありません。マークを付けると、 node
const
, 、どちらもコンパイルされません。
Node* const
のNode const*
を混乱させています。
[不幸?]ここでの間接を使用することの副作用は、ポインタメンバーの一般的な永続性があなたが動作している実際のconst
とは関係ありません。
そのメンバーがポインターになる必要がない場合は、これは楽しく簡単です:
class V
{
public:
Node node;
void const_action() const
{
node.val = 5; // error here
}
void action()
{
node.val = 5; // no error here
}
};
.
しかし、その名前を考えると、私は人生がそれほど単純ではなく、基本的には運が不足しています。
所属していません StackOverflow