- •Классы и заголовочные файлы Отделение объявления от реализации
- •Int m_month;
- •Int m_year;
- •Int getValue () { return m_value ; }
- •Int getValue () {return m_value;}
- •Классы и заголовочные файлы
- •Int getDay () {return m_day;}
- •Void Date::SetDate (int day, int month, int year) {
- •Параметры по умолчанию
- •Библиотеки
- •Заключение
- •Классы и const
- •Константные объекты классов
- •Int m_value;
- •Int getValue () { return m_value ; }
- •Int main () {
- •Константные методы классов
- •Int m_value;
- •Int m_value;
- •Int m_value;
- •Константные ссылки и классы
- •Int getDay () {return m_day;}
- •Void printDate (const Date &date) {
- •Int main () {
- •Int m_month;
- •Int m_year;
- •Void setDate (int day, int month, int year) {
- •Перегрузка константных и неконстантных функций
- •Int main () {
- •Статические переменные-члены класса
- •Статические переменные-члены класса
- •Int generateId () {
- •Int main () {
- •Int main () {
- •Int main () {
- •Статические члены не связаны с объектами класса
- •Int main () {
- •Определение и инициализация статических переменных-членов класса
- •Инициализация статических переменных-членов внутри тела класса
- •Использование статических переменных-членов класса
- •Int getId() const { return m_id; }
- •Int main () {
- •Статические методы класса
- •Int main () {
- •Int main () {
- •Статические методы не имеют указателя this
- •Int main () {
- •Предупреждение о классах со всеми статическими членами
- •Int main () {
- •Дружественные функции и классы
- •Int m_value;
- •Void reset (Anything &anything) {
- •Int main () {
- •Int m_value;
- •Дружественные функции и несколько классов
- •Дружественные классы
- •Примечания о дружественных классах:
- •Дружественные методы
- •If (m_displayIntFirst)
- •Int m_intValue;
- •Values (int intValue, double dValue) {
- •Анонимные объекты
- •Int main () {
- •Анонимные объекты класса
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Int m_dollars;
- •Int getDollars() const { return m_dollars; }
- •Int main () {
- •Вложенные типы данных в классах
- •Int main () {
- •Вложенные пользовательские типы данных в классах
- •Int main () {
- •Другие вложенные пользовательские типы данных в классах
Дружественные функции и несколько классов
Функция может быть другом сразу для нескольких классов, например:
#include <iostream>
class Humidity;
class Temperature {
private:
int m_temp;
public:
Temperature (int temp=0) {m_temp = temp;}
friend void outWeather (const Temperature &temperature, const Humidity &humidity);
};
class Humidity {
private:
int m_humidity;
public:
Humidity (int humidity=0) {m_humidity = humidity;}
friend void outWeather (const Temperature &temperature, const Humidity &humidity);
};
void outWeather (const Temperature &temperature, const Humidity &humidity) {
std::cout << "The temperature is " << temperature.m_temp <<
" and the humidity is " << humidity.m_humidity << '\n';
}
int main () {
Temperature temp (15);
Humidity hum (11);
outWeather (temp, hum);
return 0;
}
Здесь есть две вещи, на которые следует обратить внимание. Во-первых, поскольку функция outWeather () является другом для обоих классов, то она имеет доступ к закрытым членам обоих классов.
Во-вторых, обратите внимание на следующую строку в примере, приведенном выше:
class Humidity;
Это прототип класса, который сообщает компилятору, что мы определим класс Humidity чуть позже.
Без этой строчки компилятор выдал бы ошибку, что не знает, что такое Humidity при анализе прототипа дружественной функции outWeather() внутри класса Temperature.
Прототипы классов выполняют ту же роль, что и прототипы функций: они сообщают компилятору об объектах, которые позднее будут определены, но которые сейчас нужно использовать.
Однако, в отличие от функций, классы не имеют типа возврата или параметров, поэтому их прототипы предельно лаконичны: ключевое слово class + имя класса + ; (например, class Anything;).
Дружественные классы
Один класс может быть дружественным другому классу. Это откроет всем членам первого класса доступ к закрытым членам второго класса, например:
#include <iostream>
class Values {
private:
int m_intValue;
double m_dValue;
public:
Values (int intValue, double dValue) {
m_intValue = intValue;
m_dValue = dValue;
}
// Делаем класс Display другом класса Values
friend class Display;
};
class Display {
private:
bool m_displayIntFirst;
public:
Display (bool displayIntFirst) {m_displayIntFirst = displayIntFirst;}
void displayItem (Values &value)
{
if (m_displayIntFirst)
std::cout << value.m_intValue << " " << value.m_dValue << '\n';
else // или сначала выводим double
std::cout << value.m_dValue << " " << value.m_intValue << '\n';
}
};
int main () {
Values value (7, 8.4);
Display display(false);
display.displayItem (value);
return 0;
}
Поскольку класс Display является другом класса Values, то любой из членов Display имеет доступ к private-членам Values. Результат выполнения программы:
8.4 7
Примечания о дружественных классах:
- Во-первых, даже несмотря на то, что Display является другом Values, Display не имеет прямой доступ к указателю this объектов Values.
- Во-вторых, даже если Display является другом Values, это не означает, что Values также является другом Display.
- Если вы хотите сделать оба класса дружественными, то каждый из них должен указать в качестве друга противоположный класс.
- Наконец, если класс A является другом B, а B является другом C, то это не означает, что A является другом C.
Будьте внимательны при использовании дружественных функций и классов, поскольку это может нарушать принципы инкапсуляции.
Если детали одного класса изменятся, то детали класса-друга также будут вынуждены измениться. Следовательно, ограничивайте количество и использование дружественных функций и классов.
