2014-02-09 3 views
2

В этом коде панель объектов представляет собой тип const, но через функцию const я все еще могу изменить значение элемента x. Это необоснованно?Член объекта C++ const может быть изменен

выход

// overloading members on constness 
#include <iostream> 
using namespace std; 

class MyClass { 
    int x; 
    public: 
    MyClass(int val) : x(val) {} 
    int& get() const {return x;} 
    int& get() {return x;} 
}; 

int main() { 
    MyClass foo (10); 
    const MyClass bar (20); 
    foo.get() = 15;   
    bar.get() = 25;   
    cout << foo.get() << '\n'; 
    cout << bar.get() << '\n'; 

    return 0; 
} 
+4

Этот код не должен компилироваться. Вы не можете взять ссылку «T &» на объект 'const T' (который фактически становится x). – Paranaix

+0

'get() const' говорит, что функция не изменяет данные (а это не так) - не то, что возвращаемое значение является const – Rob

+0

@Paranaix, но успех компиляции – Jianchen

ответ

4
int& get() const {return x;} 

возвращается к не- const ссылки на член const объекта. (Мы знаем, что *this является const из-за объявления int& get() как const.) Это должно быть помечено как ошибка, поскольку это недопустимое преобразование (x не объявлено mutable); и gcc и clang сделают это. Тот факт, что ваш компилятор только выдал предупреждение, является странным, но, тем не менее, вы должны прислушаться к предупреждению.

Вы могли бы избежать этой ошибки, явно используя const_cast<int&>(x), но было бы неопределенное поведение (UB), чтобы попытаться использовать возвращаемый int& изменить x. Однако компилятор не обязан отмечать как ошибку или даже обнаруживать все возможные выражения, которые могут приводить к неопределенному поведению.

Короче говоря, вам разрешено стрелять в ногу, но хороший компилятор по крайней мере предупредит вас, прежде чем вы это сделаете. Слушайте предупреждения.

+0

В этом случае это не так. Компилятор должен произвести ошибку. – Puppy

+0

@DeadMG: Да, вы правы. Я удалил свой комментарий, прежде чем вы разместили свой. – TonyK

+0

@DeadMG: Да, это правда. gcc и clang оба делают. Будет редактировать. – rici

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