Другие истории, которые могут вам понравиться —
- Копирование в C++
- Спецификаторы доступа в C++
- Константные переменные в C++
- Классы в C++
- Статические члены в C++
Я уже говорил о Константных переменных в C++ в одном из наших предыдущих рассказов. Я настоятельно рекомендую вам проверить это!
В этой истории я хотел поговорить о константности применительно к классам в C++. К концу этой истории вы сможете ответить на такие вопросы, как —
- В чем разница между константным и непостоянным объектом класса?
- Какова цель константных функций-членов в C++?
- Какова семантика константных членов данных в классе C++?
Имея в виду все эти вопросы, давайте начнем с сегодняшней истории!
Понимание указателя this
Все функции-члены в C++ имеют доступ к секретному скрытому указателю с именем this. Этот указатель this указывает на ячейку памяти текущего объекта.
Для класса MyClass ниже будет определение этого указателя.
MyClass* const this;
Обратите внимание, что указатель ‘this’ является постоянным указателем, т. е. его нельзя изменить, чтобы он указывал на какой-либо другой объект. Однако это не означает, что указанные данные постоянны. (Вы можете отметить это, если это не имеет смысла!)
Вот пример использования указателя this.
class MyClass {
int myDataMember;
public:
MyClass(int myDataMember) : myDataMember(myDataMember) {}
void setMyDataMember(int value) {
// this pointer is available implicitly inside member functions
this -> myDataMember = value;
}
void print() {
std::cout << myDataMember << std::endl;
}
};
Постоянные объекты
Как и переменные встроенного типа, объекты пользовательских типов также можно сделать постоянными. Если объект помечен как константа, ни один из его элементов данных не может быть изменен.
Пометка константы объекта аналогична пометке константой переменных.
const MyClass myClass(5);
Константный объект нельзя использовать для вызова обычных методов класса, поскольку эти методы могут изменять элементы данных. Итак, что-то вроде следующего приведет к ошибке компиляции.
myClass.setDataMember(10); // Error! myClass.print(); // Error!
Читатель может решить, что ошибка setDataMember имеет смысл, так как он пытается изменить элемент данных, но почему метод print выдает ошибку? Он даже не изменяет никаких элементов данных. Чтобы понять это, нам нужно копнуть немного глубже.
Подпись указателя this немного отличается, когда объект помечен как константа.
const MyClass* const this; // Constant Pointer to Constant Object
Однако обычные функции-члены ожидают, что подпись указателя this будет следующей.
MyClass* const this; // Constant Pointer to Non-Constant Object
Компилятор не может преобразовать указатель на постоянные данные в указатель на непостоянные данные. Вот почему все вызовы обычных вызовов функций прерываются, когда объект помечен как константа.
Хорошо… Так как же решить эту проблему? Подсказка: константные функции-члены!
Постоянные функции-члены
Функции-члены с ключевым словом const, расположенным между заголовком и телом метода, называются постоянными функциями-членами. Внутри этих методов никакие члены данных не могут быть изменены или изменены.
void print() const { std::cout << myDataMember << std::endl; }
Константная функция-член ожидает, что указатель this будет указывать на константные данные. Таким образом, константные объекты могут безопасно вызывать константные функции-члены.
Кроме того, поскольку компилятор может легко преобразовать указатель на непостоянные данные в указатель на постоянные данные, все непостоянные объекты также могут обращаться к константным функциям-членам.
Все функции-члены, которым не нужно изменять данные-члены, должны быть помечены как константные!
Постоянные члены данных
Часто мы хотим, чтобы некоторые элементы данных объекта не изменялись после их инициализации. Для этого C++ предоставляет нам возможность помечать элементы данных как константы.
Константные данные-члены не могут быть изменены даже из неконстантных функций-членов. Они должны быть инициализированы только через списки инициализаторов конструктора.
На этом мы подошли к концу этой статьи. Надеюсь, сегодня вы узнали что-то новое и интересное. 🙂
Чтобы узнать больше таких статей о C++, посмотрите мою серию in C++.
Кроме того, если вам нравится моя работа, покажите свою признательность, нажав кнопку «Мне нравится»!