882 Stimmen

Bedeutung des letzten Wortes "const" in einer Funktionserklärung einer Klasse?

Was ist die Bedeutung von const in Erklärungen wie diesen? Die const verwirrt mich.

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

1 Stimmen

Bitte markieren Sie eine Antwort. Dankeschön

4 Stimmen

Ich glaube nicht, dass das möglich ist, @Jesse . Das Konto des Fragestellers ist schon seit Jahren getoastet.

1155voto

Mats Fredriksson Punkte 19007

Wenn Sie die const Schlüsselwort zu einer Methode die this Zeiger wird im Wesentlichen zu einem Zeiger auf const Objekt, und Sie können daher keine Mitgliedsdaten ändern. (Es sei denn, Sie verwenden mutable (dazu später mehr).

El const Schlüsselwort ist Teil der Funktionssignatur, was bedeutet, dass Sie zwei ähnliche Methoden implementieren können, eine, die aufgerufen wird, wenn das Objekt const und eine, die es nicht ist.

#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();
}

Dies führt zur Ausgabe

Foo
Foo const

In der Non-Const-Methode können Sie die Instanzmitglieder ändern, was Sie in der const Version. Wenn Sie die Methodendeklaration im obigen Beispiel in den nachstehenden Code ändern, werden Sie einige Fehler erhalten.

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

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

Dies ist nicht ganz richtig, denn Sie können ein Mitglied als mutable und eine const Methode kann es dann ändern. Sie wird hauptsächlich für interne Zähler und so weiter verwendet. Die Lösung dafür wäre der folgende Code.

#include <iostream>

class MyClass
{
private:
    mutable int counter;
public:

    MyClass() : counter(0) {}

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

    void Foo() const
    {
        counter++;    // This works because counter is `mutable`
        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 << "Foo has been invoked " << ccc.GetInvocations() << " times" << std::endl;
}

die Folgendes ausgeben würde

Foo
Foo const
Foo has been invoked 2 times

213voto

Blair Conrad Punkte 217777

Das const bedeutet, dass die Methode verspricht, keine Mitglieder der Klasse zu verändern. Sie können die so gekennzeichneten Mitglieder des Objekts ausführen, auch wenn das Objekt selbst mit const :

const foobar fb;
fb.foo();

wäre legal.

Ver Wie viele und welche Verwendungen gibt es für "const" in C++? für weitere Informationen.

52voto

JaredPar Punkte 699699

El const bedeutet, dass die Methoden für jeden Wert von foobar . Der Unterschied ergibt sich, wenn Sie eine Nicht-Konst-Methode für ein Konst-Objekt aufrufen. Überlegen Sie, ob Ihre foobar Typ hatte die folgende zusätzliche Methodendeklaration:

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

Die Methode bar() ist nicht konstant und kann nur von nicht-konstanten Werten aus aufgerufen werden.

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

Die Idee dahinter const ist es jedoch, Methoden zu markieren, die den internen Zustand der Klasse nicht verändern werden. Dies ist ein leistungsfähiges Konzept, das aber in C++ nicht wirklich durchsetzbar ist. Es handelt sich eher um ein Versprechen als um eine Garantie. Und ein Versprechen, das oft und leicht gebrochen wird.

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

32voto

Mykola Golubyev Punkte 54937

Diese const bedeuten, dass der Compiler einen Fehler macht, wenn die Methode 'with const' interne Daten ändert.

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_;
};

Der 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
}

Lesen Sie ce für weitere Informationen

14voto

Alnitak Punkte 324207

Blairs Antwort trifft den Nagel auf den Kopf.

Es ist jedoch zu beachten, dass es eine mutable der den Datenelementen einer Klasse hinzugefügt werden kann. Jedes so gekennzeichnete Mitglied kann geändert werden in einer const Methode, ohne gegen die const Vertrag.

Dies ist z. B. dann sinnvoll, wenn Sie möchten, dass sich ein Objekt merkt, wie oft eine bestimmte Methode aufgerufen wurde, ohne dass dies Auswirkungen auf die "logische" Konstante dieser Methode hat.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X