Ответ
Константный метод (объявленный с ключевым словом const после списка параметров) гарантирует, что этот метод не будет изменять нестатические члены данных объекта (за исключением членов, объявленных как mutable). Это мощный инструмент проектирования интерфейсов, обеспечивающий корректность, безопасность и ясность кода.
Основные цели:
- Гарантия корректности для константных объектов: Константный метод — единственный тип метода, который можно вызвать у объекта, объявленного как
const. - Явное проектирование контракта: Сигнатура метода сообщает пользователю класса, изменяет ли он состояние объекта (неконстантный метод) или только читает его (константный метод).
- Предотвращение случайных изменений: Компилятор становится стражем, не позволяющим константному методу модифицировать объект.
- Возможность оптимизации: Компилятор может делать определенные предположения для константных методов, потенциально оптимизируя вызовы.
Пример:
class BankAccount {
private:
mutable std::mutex mtx; // mutable: может быть изменен в const-методе
double balance;
int transactionCount;
public:
// Константный метод доступа (геттер) — не меняет логическое состояние
double getBalance() const {
std::lock_guard<std::mutex> lock(mtx); // OK, mtx - mutable
return balance;
}
// Константный метод, выполняющий логирование
void printStatement() const {
// transactionCount++; // ОШИБКА компиляции: попытка изменить не-mutable член
std::cout << "Balance: " << balance << "n";
}
// Неконстантный метод — изменяет состояние объекта
void deposit(double amount) {
if (amount > 0) {
balance += amount;
transactionCount++;
}
}
};
int main() {
BankAccount myAccount;
myAccount.deposit(100.0); // OK: вызов неконстантного метода
std::cout << myAccount.getBalance(); // OK: вызов константного метода
const BankAccount& constRef = myAccount;
// constRef.deposit(50.0); // ОШИБКА: нельзя вызвать неконстантный метод через const-ссылку
std::cout << constRef.getBalance(); // OK: константный метод доступен
}
Перегрузка по const: Можно иметь две версии одного метода — константную и неконстантную. Это часто используется для оператора доступа по индексу, чтобы возвращать константную или неконстантную ссылку в зависимости от константности объекта.
class MyArray {
int data[10];
public:
const int& operator[](size_t idx) const { return data[idx]; } // Для const объектов
int& operator[](size_t idx) { return data[idx]; } // Для не-const объектов
};