Скачать презентацию
Идет загрузка презентации. Пожалуйста, подождите
Презентация была опубликована 9 лет назад пользователемАлина Загоскина
1 Лекция 10. Введение в ООП. Часть 3 Красс Александр СПбГУ ИТМО, 2008
2 2 Темы Члены класса Списки инициализации Перегрузка функций
3 3 Повторение. Простая реализация class String { public: String(const char *str) { data_ = new char[strlen(str) + 1]; strcpy(data_, str); } void Add(const char *str) {... } private: char *data_; };... String str1(AAA);
4 4 Члены класса Пусть класс X содержит член y типа Y. Тогда y может быть объявлен тремя способами: –Y y; // Как объект –Y &y; // Как ссылка –Y *y; // Как указатель
5 5 Члены класса Желательно использовать член класса типа объект, поскольку это самый простой способ. Используйте указатель, если … –Вам нужен массив объектов –Вам нужно ссылаться на внешний объект Используйте ссылки если … –Вам нужно ссылаться на внешний объект
6 6 Списки инициализации class Person { const char *firstName_; const char *lastName_; int dayOfBirth_; public: Person(const char *firstName, const char *lastName, int dayOfBirth); const char* GetFirstName(); const char* GetLastName(); int GetDayOfBirth(); };
7 7 Списки инициализации Person::Person(const char *firstName, const char *lastName, int dayOfBirth) { firstName_ = firstName; lastName_ = lastName; dayOfBirth_ = dayOfBirth; }
8 8 Списки инициализации Person::Person(const char *firstName, // Обычный const char *lastName, int dayOfBirth) // способ { firstName_ = firstName; // Работать не будет, lastName_ = lastName; // т.к. const char * dayOfBirth_ = dayOfBirth; } Person::Person(const char *firstName, const char *lastName, int dayOfBirth) : firstName_(firstName), lastName_(lastName), dayOfBirth_(dayOfBirth) // Список инициализации { }
9 9 Списки инициализации Какой способ лучше? –Для встроенных типов (int, char) разницы нет. –Для пользовательских типов списки инициализации предпочтительнее При инициализации присваиванием (в конструкторе) для них сначала будет вызван конструктор по умолчанию, а потом оператор присваивания. При инициализации списком будет вызван только конструктор, подходящий для указанного аргумента.
10 10 Списки инициализации struct A { int i; A(); A(int k); }; A::A() : i(-1) {} A::A(int k) : i(k) {} struct B { A b, a; int j, k; B(); }; B::B() : a(1), b(a.i + 1), j(a.i), k(j + A().i) { cout << a.i << endl; cout << b.i << endl; cout << j << endl; cout << k << endl; } void main() // Что мы должны { // увидеть на B b; // экране? }
11 11 Списки инициализации struct A { int i; A(); A(int k); }; A::A() : i(-1) {} A::A(int k) : i(k) {} struct B { A b, a; int j, k; B(); }; B::B() : a(1), b(a.i + 1), j(a.i), k(j + A().i) { cout << a.i << endl; cout << b.i << endl; cout << j << endl; cout << k << endl; } void main() // 1 { // мусор B b; // 1 } // 0
12 12 Списки инициализации При использовании списка инициализации члены класса инициализируются в порядке определения в классе, а не в порядке перечисления в списке!
13 13 Списки инициализации Для каких полей класса не избежать применения списков инициализации: для членов класса, чьи пользовательские типы не имеют конструкторов по умолчанию. для константных членов класса (const int). для ссылки (char &).
14 14 Итого Списки инициализации предпочтительнее инициализации в конструкторе (присваивания). В списке инициализации перечисляйте члены класса в порядке их объявления в классе. Используйте списки инициализации даже для встроенных типов (порядка ради). Не бойтесь пустых тел конструкторов, возникающих из-за списков инициализации.
15 15 Сигнатура функции Сигнатура функции – список типов параметров функции Примеры: –int f1 (int, double); –int f2 (int, const char*, const char*); Имена параметров не участвуют в определении сигнатуры, поэтому мы их указывать не будем. Модификатор const изменяет сигнатуру функции. Тип возвращаемого значения не влияет на сигнатуру
16 16 Перегрузка функций Функции в одной области видимости могут иметь одно и тоже имя, но разную сигнатуру. В этом случае говорят, что функции перегружены. Пример: –int Max (int, int); –int Max (const int*, int); Каждая из этих функций будет реализована отдельно (по своим алгоритмам), но с точки зрения пользователя, существует только одна функция.
17 17 Перегрузка функций Жизнь без перегрузки функций была бы тяжелой: –int IntMax (int, int); –int IntArrayMax (const int*, int); –int IntArraysMax (const int*, const int*);
18 18 Перегрузка функций Как компилятор понимает, какую функцию надо вызвать? –Он может попытаться найти функцию, сигнатура которой точно соответствует передаваемым параметрам. –Он может попытаться применить неявные преобразования, используя конструкторы и перегруженные операторы преобразования типов. В любом случае, для того, чтобы перегрузка работала, сигнатуры функций должны существенно различаться: –int f (int); –int f (int&); // Ошибка!
19 19 Перегрузка функций Функции могут различаться по их константности. Рассмотрим функцию at из класса Array: –int& at(int index); –const int& at(int index) const; Функции не могут различаться только типом возвращаемого значения! –int f (int); –double f (int); // Ошибка!
20 20 Спасибо за внимание Вопросы?
Еще похожие презентации в нашем архиве:
© 2024 MyShared Inc.
All rights reserved.