Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лекции / Лекция 3-4n.docx
Скачиваний:
0
Добавлен:
11.02.2026
Размер:
74.69 Кб
Скачать

Константные ссылки и классы

Еще одним способом создания константных объектов является передача объектов в функцию по константной ссылке.

Мы рассмотрели преимущества передачи аргументов по константной ссылке, нежели по значению.

Если вкратце, то передача аргументов по значению создает копию значения (что является медленным процессом).

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

Мы обычно делаем ссылку константной для гарантии того, что функция не изменит значение аргумента и работает с  r-values, например, с литералами.

Можете ли вы определить, что не так со следующим кодом?

#include <iostream>

class Date {

private:

int m_day;

int m_month;

int m_year;

public:

Date (int day, int month, int year) {

setDate (day, month, year);

}

void setDate (int day, int month, int year) {

m_day = day;

m_month = month;

m_year = year;

}

Int getDay () {return m_day;}

int getMonth () {return m_month;}

int getYear () {return m_year;}

};

// Примечание: Мы передаем объект date по константной ссылке, дабы //избежать создания копии объекта date

Void printDate (const Date &date) {

std::cout << date.getDay () << "." << date.getMonth () << "." << date.getYear () << '\n';

}

Int main () {

Date date (12, 11, 2018);

printDate (date);

return 0;

}

Ответ заключается в том, что внутри функции printDate (), объект date рассматривается как константный. И через этот константный date мы вызываем методы getDay (), getMonth () и getYear (), которые являются неконстантными.

Поскольку мы не можем вызывать неконстантные методы через константные объекты, то здесь мы получим ошибку компиляции.

Решение простое — сделать getDay(), getMonth() и getYear() константными:

class Date {

private:

int m_day;

Int m_month;

Int m_year;

public:

Date (int day, int month, int year) {

setDate (day, month, year);

}

// Метод setDate () не может быть const, так как изменяет значения //переменных-членов

Void setDate (int day, int month, int year) {

m_day = day;

m_month = month;

m_year = year;

}

// Все следующие геттеры могут быть const

int getDay () const {return m_day;}

int getMonth () const {return m_month;}

int getYear () const {return m_year;}

Теперь в функции printDate () константный date сможет вызывать getDay (), getMonth () и getYear ().

Перегрузка константных и неконстантных функций

Хотя это делается не очень часто, но функцию можно перегрузить таким образом, чтобы иметь константную и неконстантную версии одной и той же функции:

#include <string>

class Anything {

private:

std::string m_value;

public:

Anything (const std::string &value="") { m_value= value; }

const std::string& getValue() const { return m_value; } // getValue()

//для константных объектов

std::string& getValue() { return m_value; } // getValue() для

// неконстантных объектов

};

Константная версия функции будет вызываться для константных

объектов, а неконстантная версия будет вызываться для неконстантных объектов: