2012-07-02 3 views
3

Зачем компилятор жалуется на указанную строку?Почему я получаю ошибку -fpermissive с этим кодом?

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 

}; 
+2

'-fpermissive' не является ошибкой, это флаг для управления сгенерированными ошибками. См. [Что делает флаг fpermissive?] (Http://stackoverflow.com/questions/8843818/what-does-the-fpermissive-flag-do) –

ответ

5

Вы должны объявить функцию Get() быть const:

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

Даже если Get() не изменяет значения членов, компилятор проинструктирован только позволяют вызывать функции, которые явно помечены const.

gcc инструктирует вас, что вы можете отменить жалобу, используя аргумент -fpermissive; однако, как правило, лучше не делать этого (иначе зачем вообще объявлять const?). Как правило, лучше убедиться, что каждая функция-член, вызываемая параметром const, является функцией-членом const.

Эта статья, касающаяся Const Correctness, очень интересна.

3

Внутри вашего объекта operator =c является постоянным объектом: он имеет const C тип. На языке C++ вам не разрешено вызывать не константные функции-члены постоянных объектов. То есть вызов c.Get() является незаконным, так как ваш Get является непостоянной функцией-членом. Вот почему компилятор сообщает об ошибке.

Либо сделайте свой c непостоянным (как в вашей прокомментированной версии кода), либо сделайте Get константой. Вам решать, какой подход правильный, но похоже, что вы должны сделать последнее.

В качестве примечания стороны не так много декларируется Get() как возвращающийся const std::string. Если вы возвращали его по ссылке (как const std::string &), тогда было бы целесообразно, чтобы const. Но поскольку вы возвращаетесь по значению, объявление возвращаемого типа как const не так уж и полезно. Это вопрос вашего личного стиля.

+0

Что касается вашего побочного элемента: возврат строки в качестве значения const не разрешить перемещение строки. То есть, значение будет использовать конструктор копирования std :: string, а не конструктор перемещения, поскольку вы не можете использовать const string для string &&. –

Смежные вопросы