c++ - const用法




C++方法聲明中最後一個“const”的含義? (5)

const在這些聲明中的含義是什麼? const讓我困惑。

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

const意味著該方法承諾不會改變該類的任何成員。 即使對象本身被標記為const ,您也可以執行已標記的對象成員:

const foobar fb;
fb.foo();

將是合法的。

查看C ++中“const”的用法和用法? 了解更多信息。


C ++中 常量成員函數的含義 常識:基本中級編程給出了一個清晰的解釋:

這個指針在X類的非const成員函數中的類型是X * const。 也就是說,它是一個指向非常數X的常量指針(參見Const指針和指向Const的指針[7,21])。 因為這個引用的對像不是const的,所以它可以被修改。 類X的const成員函數中的類型是const X * const。 也就是說,它是一個常量X的常量指針。因為這個引用的對像是const,所以它不能被修改。 這是const和非const成員函數的區別。

所以在你的代碼中:

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

你可以這樣想:

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

const關鍵字添加到方法時, this指針實際上將成為指向const對象的指針,因此不能更改任何成員數據。 (除非你使用mutable ,稍後更多)。

const關鍵字是函數簽名的一部分,這意味著您可以實現兩個類似的方法,一個是在對象為const時調用,另一個不是。

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

這將輸出

Foo
Foo const

在非const方法中,您可以更改實例成員,這是您在const版本中無法做到的。 如果將上例中的方法聲明更改為下面的代碼,則會出現一些錯誤。

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

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

這並不完全正確,因為您可以將成員標記為mutable ,然後可以使用const方法更改它。 它主要用於內部計數器和東西。 解決方案是下面的代碼。

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

這將輸出

Foo
Foo const
The MyClass instance has been invoked 2 times

布萊爾的回答是關鍵。

但請注意,有一個mutable限定符可以添加到類的數據成員中。 任何如此標記的成員可以在不違反const約定的情況下在const方法中進行修改。

如果你想要一個對象記住一個特定的方法被調用了多少次,而不影響該方法的“邏輯”常量,你可能想要使用它(例如)。


這些常量意味著,如果'with const'方法更改內部數據,編譯器將會出錯。

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

考試

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
}

閱讀this以獲取更多信息





c++-faq