Question

J'essaie d'avoir une opération const sur une classe qui est vraiment const - cela ne change pas les données vers lesquelles pointe la classe.

Par exemple:

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
    }
};
Était-ce utile?

La solution

Vous pouvez utiliser un modèle pour appliquer la Const bien l'exactitude sur un pointeur sans modifier le sens ni la mise en œuvre de votre 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
    }
};

Autres conseils

const après une déclaration de fonction, il est indiqué que la fonction n'est pas autorisée à modifier les membres de la classe (sauf ceux marqués mutable).

Puisque votre code ne modifie aucun membre de la classe et modifie uniquement l'objet node pointe vers, les deux fonctions seront compilées.

AFAIK, il n'y a aucun moyen d'empêcher cela.Si vous marquez le node const, ni l’un ni l’autre ne compilera.

Tu es confus Node* const pour Node const*.

Un effet secondaire [malheureux ?] de l'utilisation de l'indirection ici est que constl'état du membre pointeur n'a rien à voir avec la réalité Node sur lequel vous opérez.

Si vous n'avez pas besoin que ce membre soit un pointeur, alors c'est agréablement simple :

class V
{
public:
    Node node;

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

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

Cependant, étant donné son nom, je soupçonne que la vie n’est pas si simple et que vous n’avez pratiquement pas de chance.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top