Question Signification de 'const' dernier dans une déclaration de fonction d'une classe?


Quel est le sens de const dans des déclarations comme celles-ci? le const me confond.

class foobar
{
  public:
     operator int () const;
     const char* foo() const;
};

590
2018-04-15 13:27


origine


Réponses:


Lorsque vous ajoutez le const mot-clé à une méthode this pointeur deviendra essentiellement un pointeur vers const objet, et vous ne pouvez donc pas modifier les données des membres. (Sauf si vous utilisez mutable, plus sur cela plus tard).

le const mot-clé fait partie de la signature des fonctions, ce qui signifie que vous pouvez implémenter deux méthodes similaires, une qui est appelée lorsque l'objet est constet un qui ne l'est pas.

#include <iostream>

class MyClass
{
private:
    int counter;
public:
    void Foo()
    { 
        std::cout << "Foo" << std::endl;    
    }

    void Foo() const
    {
        std::cout << "Foo const" << std::endl;
    }

};

int main()
{
    MyClass cc;
    const MyClass& ccc = cc;
    cc.Foo();
    ccc.Foo();
}

Cela va sortir

Foo
Foo const

Dans la méthode non-const, vous pouvez modifier les membres de l'instance, ce que vous ne pouvez pas faire dans const version. Si vous modifiez la déclaration de méthode dans l'exemple ci-dessus pour le code ci-dessous, vous obtiendrez quelques erreurs.

    void Foo()
    {
        counter++; //this works
        std::cout << "Foo" << std::endl;    
    }

    void Foo() const
    {
        counter++; //this will not compile
        std::cout << "Foo const" << std::endl;
    }

Ce n'est pas complètement vrai, car vous pouvez marquer un membre comme mutable et un const méthode peut alors le changer. Il est principalement utilisé pour les compteurs internes et autres. La solution pour cela serait le code ci-dessous.

#include <iostream>

class MyClass
{
private:
    mutable int counter;
public:

    MyClass() : counter(0) {}

    void Foo()
    {
        counter++;
        std::cout << "Foo" << std::endl;    
    }

    void Foo() const
    {
        counter++;
        std::cout << "Foo const" << std::endl;
    }

    int GetInvocations() const
    {
        return counter;
    }
};

int main(void)
{
    MyClass cc;
    const MyClass& ccc = cc;
    cc.Foo();
    ccc.Foo();
    std::cout << "The MyClass instance has been invoked " << ccc.GetInvocations() << " times" << endl;
}

ce qui produirait

Foo
Foo const
The MyClass instance has been invoked 2 times

774
2018-04-15 13:49



Le const signifie que la méthode promet de ne modifier aucun membre de la classe. Vous seriez en mesure d'exécuter les membres de l'objet qui sont marqués, même si l'objet lui-même était marqué const:

const foobar fb;
fb.foo();

serait légal.

Voir Combien et quelles sont les utilisations de "const" en C ++? pour plus d'informations.


170
2018-04-15 13:29



le const qualificatif signifie que les méthodes peuvent être appelées sur toute valeur de foobar. La différence survient lorsque vous envisagez d'appeler une méthode non-const sur un objet const. Considérez si votre foobar type a la déclaration de méthode supplémentaire suivante:

class foobar {
  ...
  const char* bar();
}

La méthode bar() est non-const et ne peut être accédé qu'à partir de valeurs non-const.

void func1(const foobar& fb1, foobar& fb2) {
  const char* v1 = fb1.bar();  // won't compile
  const char* v2 = fb2.bar();  // works
}

L'idée derrière const cependant est de marquer des méthodes qui ne modifieront pas l'état interne de la classe. C'est un concept puissant mais qui n'est pas réellement applicable en C ++. C'est plus une promesse qu'une garantie. Et celui qui est souvent cassé et facilement cassé.

foobar& fbNonConst = const_cast<foobar&>(fb1);

38
2018-04-15 13:30



Ces const signifient que le compilateur va Erreur si la méthode 'avec const' change les données internes.

class A
{
public:
    A():member_()
    {
    }

    int hashGetter() const
    {
        state_ = 1;
        return member_;
    }
    int goodGetter() const
    {
        return member_;
    }
    int getter() const
    {
        //member_ = 2; // error
        return member_;
    }
    int badGetter()
    {
        return member_;
    }
private:
    mutable int state_;
    int member_;
};

Le test

int main()
{
    const A a1;
    a1.badGetter(); // doesn't work
    a1.goodGetter(); // works
    a1.hashGetter(); // works

    A a2;
    a2.badGetter(); // works
    a2.goodGetter(); // works
    a2.hashGetter(); // works
}

Lis ce pour plus d'informations


20
2018-04-15 13:30



La réponse de Blair est sur la marque.

Cependant, notez qu'il y a un mutable qualificateur qui peut être ajouté aux membres de données d'une classe. Tout membre si marqué pouvez être modifié dans un const méthode sans violer la const Contrat.

Vous pouvez utiliser ceci (par exemple) si vous voulez qu'un objet se souvienne du nombre de fois qu'une méthode particulière est appelée, sans affecter la constance "logique" de cette méthode.


9
2018-04-15 13:37



Signification d'une fonction membre Const dans C ++ Connaissance commune: Programmation intermédiaire essentielle donne une explication claire:

Le type de ce pointeur dans une fonction membre non-const d'une classe   X est X * const. Autrement dit, c'est un pointeur constant vers un X non constant   (Voir les pointeurs de Const et les pointeurs vers Const [7, 21]). Parce que l'objet   auquel cela se réfère n'est pas const, il peut être modifié. Le type de   ceci dans une fonction membre const d'une classe X est const X * const. Cette   est, c'est un pointeur constant vers une constante X. Parce que l'objet à   ce qui se réfère est const, il ne peut pas être modifié. C'est le   différence entre les fonctions membres const et non-const.

Donc dans votre code:

class foobar
{
  public:
     operator int () const;
     const char* foo() const;
};

Vous pouvez le penser comme ceci:

class foobar
{
  public:
     operator int (const foobar * const this) const;
     const char* foo(const foobar * const this) const;
};

6
2018-03-14 05:48



quand vous utilisez const dans la signature de la méthode (comme votre dit: const char* foo() const;) vous dites au compilateur que la mémoire pointée par this ne peut pas être changé par cette méthode (qui est foo ici).


4
2018-05-30 05:54