3

指定された行でコンパイラが文句を言うのはなぜですか?

class C
{
    std::string s;
public:
    C() { s = "<not set>";}
    ~C() {}
    void Set(const std::string ss) { s=ss; }
    const std::string Get() { return s; }

    C &operator=(const C &c) { Set(c.Get()); return *this; }
    //error: passing ‘const C’ as ‘this’ argument of ‘const string C::Get()’
    // discards qualifiers [-fpermissive]


    //C &operator=(C &c) { Set(c.Get()); return *this; }   <-- works fine

};
4

2 に答える 2

5

Get()関数を次のように宣言する必要がありますconst

const std::string Get() const { return s; }

メンバー値は変更されませGet()んが、明示的にラベル付けされた関数のみを呼び出せるようにコンパイラに指示されconstます。

-fpermissivegcc は、引数;を使用して苦情をオーバーライドできることを指示しています。ただし、一般的にはこれを行わない方がよいでしょう (そうしないと、何も宣言する必要がありませconstん)。一般に、constパラメーターで呼び出されるすべてのメンバー関数がメンバー関数であることを確認することをお勧めしconstます。

Const Correctnessに関するこの記事は非常に興味深いものです。

于 2012-07-02T23:14:19.630 に答える
3

オブジェクトの内部には定数オブジェクトがあります。これにはoperator =型があります。C++ 言語では、定数オブジェクトの非定数メンバー関数を呼び出すことはできません。つまり、 yourは非定数メンバー関数であるため、呼び出しは違法です。これが、コンパイラがエラーを報告する理由です。cconst Cc.Get()Get

非定数にするかc(コードのコメントアウト バージョンのように)、Get定数にします。どちらのアプローチが正しいかを決めるのはあなた次第ですが、後者を行うべきだと思われます。

Get()補足として、 returnとして宣言する意味はあまりありませんconst std::stringconst std::string &参照によって( として)返す場合は、それconstが適切です。ただし、値で返すため、戻り値の型を as として宣言することconstはあまり役に立ちません。それはあなたの個人的なスタイルの問題です。

于 2012-07-02T23:16:40.020 に答える