ポインター間で const の正確性を維持するにはどうすればよいですか?

StackOverflow https://stackoverflow.com//questions/21065391

  •  26-12-2019
  •  | 
  •  

質問

本当に 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* constNode const*を混乱させています。

[不幸?]ここでの間接を使用することの副作用は、ポインタメンバーの一般的な永続性があなたが動作している実際のconstとは関係ありません。

そのメンバーがポインターになる必要がない場合は、これは楽しく簡単です:

class V
{
public:
    Node node;

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

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

しかし、その名前を考えると、私は人生がそれほど単純ではなく、基本的には運が不足しています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top