Партнерка на США и Канаду по недвижимости, выплаты в крипто

  • 30% recurring commission
  • Выплаты в USDT
  • Вывод каждую неделю
  • Комиссия до 5 лет за каждого referral

Операция -> применяется для выбора члена объекта, заданного указателем.

Функции-члены класса в языке С++. Друзья класса в языке С++

Функция, описанная как элемент (без спецификатора friend), называется функцией-членом и вызывается, используя синтаксис элемента класса.

Определение функции-члена действует только внутри области действия его класса. Это означает, что он может явно использовать имена своего класса.

В функции-члене элемент имени ссылается на тот объект, для которого была вызвана функция.

В функции-члене ключевое слово this указывает на объект, для которого вызывается функция.

Пример:

class date {

int month, day, year;

public:

void set(int, int, int);

void get(int*, int* int*);

void next();

void print();

};

В данном примере функции set, get, next, print – функции-члены класса.

Эти функции имеют полный доступ к скрытой (private) части класса date.

Пусть определены два класса: vector (вектор) и matrix (матрица). Каждый из них скрывает свое представление, но дает полный набор операций для работы с объектами его типа. Допустим, надо определить функцию, умножающую матрицу на вектор. Для простоты предположим, что вектор имеет четыре элемента с индексами от 0 до 3, а в матрице четыре вектора тоже с индексами от 0 до 3. Доступ к элементам вектора обеспечивается функцией elem(), и аналогичная функция есть для матрицы. Можно определить глобальную функцию multiply (умножить) следующим образом:

vector multiply(const matrix& m, const vector& v);

{

НЕ нашли? Не то? Что вы ищете?

vector r;

for (int i = 0; i<3; i++) { // r[i] = m[i] * v;

r. elem(i) = 0;

for (int j = 0; j<3; j++)

r. elem(i) +=m. elem(i, j) * v. elem(j);

}

return r;

Это вполне естественное решение, но оно может оказаться очень неэффективным. При каждом вызове multiply() функция elem() будет вызываться 4*(1+4*3) раз. Если в elem() проводится настоящий контроль границ массива, то на такой контроль будет потрачено значительно больше времени, чем на выполнение самой функции, и в результате она окажется непригодной для пользователей. С другой стороны, если elem() есть некий специальный вариант доступа без контроля, то тем самым мы засоряем интерфейс с вектором и матрицей особой функцией доступа, которая нужна только для обхода контроля.

Если можно было бы сделать multiply членом обоих классов vector и matrix, мы могли бы обойтись без контроля индекса при обращении к элементу матрицы, но в то же время не вводить специальной функции elem(). Однако, функция не может быть членом двух классов.

Надо иметь в языке возможность предоставлять функции, не являющейся членом, право доступа к частным членам класса. Функция - не член класса, - имеющая доступ к его закрытой части, называется другом этого класса. Функция может стать другом класса, если в его описании она описана как friend (друг). Например:

class matrix;

class vector {

float v[4];

// ...

friend vector multiply(const matrix&, const vector&);

};

class matrix {

vector v[4];

// ...

friend vector multiply(const matrix&, const vector&);

};

Функция-друг не имеет никаких особенностей, за исключением права доступа к закрытой части класса. В частности, в такой функции нельзя использовать указатель this, если только она действительно не является членом класса. Описание friend является настоящим описанием. Оно вводит имя функции в область видимости класса, в котором она была описана, и при этом происходят обычные проверки на наличие других описаний такого же имени в этой области видимости. Описание friend может находиться как в общей, так и в частной частях класса, это не имеет значения.

Теперь можно написать функцию multiply, используя элементы вектора и матрицы непосредственно:

vector multiply(const matrix& m, const vector& v)

{

vector r;

for (int i = 0; i<3; i++) { // r[i] = m[i] * v;

r. v[i] = 0;

for ( int j = 0; j<3; j++)

r. v[i] +=m. v[i][j] * v. v[j];

}

return r;

Отметим, что подобно функции-члену дружественная функция явно описывается в описании класса, с которым дружит. Поэтому она является неотъемлемой частью интерфейса класса наравне с функцией-членом.

Функция-член одного класса может быть другом другого класса:

class x {

// ...

void f();

};

class y {

// ...

friend void x::f();

};

Вполне возможно, что все функции одного класса являются друзьями другого класса. Для этого есть краткая форма записи:

class x {

friend class y;

// ...

};

В результате такого описания все функции-члены y становятся друзьями класса x.

Область видимости класса в языке С++

Член класса может быть частным (private), защищенным (protected) или общим (public):

- Частный член класса X могут использовать только функции-члены и друзья класса X.

- Защищенный член класса X могут использовать только функции-члены и друзья класса X, а так же функции-члены и друзья всех производных от X классов.

- Общий член можно использовать в любой функции.

Эти правила соответствуют делению обращающихся к классу функций на три вида: функции, реализующие класс (его друзья и члены), функции, реализующие производный класс (друзья и члены производного класса) и все остальные функции.

Контроль доступа применяется единообразно ко всем именам. На контроль доступа не влияет, какую именно сущность обозначает имя. Это означает, что частными могут быть функции-члены, константы и т. д. наравне с частными членами, представляющими данные.

Инициализация класса в языке С++

Функция, явно предназначенная для инициализации объектов, называется конструктором. Эту функцию легко распознать - она имеет то же имя, что и ее класс:

class date {

// ...

date(int, int, int);

};

Если в классе есть конструктор, все объекты этого класса будут проинициализированы. Если конструктору требуются параметры, их надо указывать:

date today = date(23,6,1983);

date xmas(25,12,0); // краткая форма

date my_birthday; // неправильно, нужен инициализатор

Часто бывает удобно указать несколько способов инициализации объекта. Для этого нужно описать несколько конструкторов:

class date {

int month, day, year;

public:

date(int, int, int); // день, месяц, год

date(int, int); // день, месяц и текущий год

date(int); // день и текущие год и месяц

date(); // стандартное значение: текущая дата

date(const char*); // дата в строковом предст.

};

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

Для конструкторов существует несколько важных правил:

·  Имя конструктора совпадает с именем его класса

·  Конструктор не имеет никакого возвращаемого значения (даже void)

·  Классу без конструктора представляется конструктор по умолчанию

·  Если конструктор описан явно, то конструктор по умолчанию не генерируется

·  Конструкторы могут быть перегружены.

·  Конструкторы не наследуются.

·  Указатель на конструктор не может быть определен.

·  Конструктор не может вызываться явно из пределов программы.

·  Конструкторы могут выполнять неявное преобразование типов.

·  Конструктор может быть объявлен с ключевым словом explicit. Такой конструктор не позволяет производить неявное преобразование типов.

2. Наследование в языке С++.

Наследование — один из четырёх важнейших механизмов объектно-ориентированного программирования (наряду с абстракцией, инкапсуляцией и полиморфизмом), позволяющий описать новый класс на основе уже существующего (родительского), при этом свойства и функциональность родительского класса наследуются новым классом.

Самая простая форма наследования включает базовый и производный классы. Путем наследования устанавливается, что производный класс дополнительно к приведенным в его определении элементам (данным-членам и функциям-членам) располагает всеми элементами базового класса. Практически каждый класс может быть производным от другого класса. Иерархия классов должна соответствовать следующим критериям:

·  Критерий включения. Объекты производных классов должны обладать всеми свойствами базовых классов.

·  Критерий независимости. Наследуемые свойства не должны ограничивать использование собственных элементов производного класса.

·  Критерий специализации. Если производный класс приводит к специализации (ограничению) свойств базового класса, то это является нарушением критерия независимости. Для восстановления корректного наследования необходимо воспользоваться полиморфизмом. Классы, которые отличаются только специализацией, обычно составляют один уровень иерархии.

·  Критерий единства. Наследование и полиморфизм обеспечивают единообразное выполнение аналогичных функций классов.

Синтаксическая конструкция наследования:

class имя_класса : список_базовых_классов{список_элементов_класса}

В списке_базовых_классов перечисляются имена базовых классов (разделяемые запятыми), свойства которых наследуются созданным классом. Запись в этом списке имеет следующий синтаксис: [virtual][public, protected, private] имя_базового_класса

Простое наследование

В некоторых языках используются абстрактные классы. Абстрактный класс — это класс, который описан в программе, имеет поля, функции, но не используется для создания объекта. Объекты создаются только на основе производных классов, наследованных от абстрактного. Базовый класс должен быть описан до того, как он может быть использован в списке_базовых_классов.

Атрибуты доступа public, protected, private используются для изменения права доступа к наследуемым элементам. Изменения прав доступа относится только к производному классу и состоит либо в сохранении наследуемых прав, либо в их ограничении (но не в расширении).

class Basis {

int value; //private

public:

int b;

};

class Inherit : private Basis {

int value;

public:

Basis::b; //опять public

Множественное наследование

При множественном наследовании у класса может быть более одного предка. В этом случае класс наследует методы всех предков. Достоинства такого подхода в большей гибкости. Множественное наследование — потенциальный источник ошибок, которые могут возникнуть из-за наличия одинаковых имен методов в предках. Подобный конфликт устраняется с помощью оператора расширения области видимости(::).

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71