Материалы (10) (1115037), страница 2
Текст из файла (страница 2)
явно,2. в случае:Box a (1, 2, 3);Box b = a; // a – параметр конструктора копирования,3. в случае:Box c = Box (3, 4, 5);// сначала создается временный объект и вызывается// обычный конструктор, а затем работает конструктор// копирования при создании объекта с; если компилятор// оптимизирующий, вызывается только обычный// конструктор с указанными параметрами;4. при передаче параметров функции по значению (при созданиилокального объекта);5. при возвращении результата работы функции в виде объекта.Вызов других конструкторов1.явно,2.при создании объекта (при обработке описания объекта),3.при создании объекта в динамической памяти (по new), при этомсначала в «куче» отводится необходимая память, а затемработает соответствующий конструктор,4.при композиции объектов наряду с собственным конструкторомвызывается конструктор объекта – члена класса,5.при создании объекта производного класса также вызываетсяконструктор и базового класса,6.при автоматическом приведении типа с помощью конструкторапреобразования.Вызов деструктора1.
явно,2. при свертке стека - при выходе из блока описания объекта, вчастности при обработке исключений, завершении работы функции;3. при уничтожении временных объектов - сразу, как толькозавершается конструкция, в которой они использовались;4. при выполнении операции delete для указателя на объект(инициализация указателя - с помощью операции new), при этомсначала работает деструктор, а затем освобождается память.5. при завершении работы программы при удаленииглобальных/статических объектов.Конструкторы вызываются в порядке определения объектов вблоке.
При выходе из блока для всех автоматических объектоввызываются деструкторы, в порядке, противоположном порядкувыполнения конструкторов.Друзья классаДруг класса – это функция, не являющаяся членом этого класса,но имеющая доступ к его private и protected членам.Своих друзей класс объявляет сам в любой зоне описания классас помощью служебного слова friend.Функция-друг может быть описана внутри класса.Если функций, имена которых совпадают с объявленной в классефункцией-другом, несколько, то другом считается только та, укоторой в точности совпадает прототип.Другом класса может быть:- обычная функция:- функция-член другого класса:- весь класс:friend void f (...);friend void Y::f (..);friend class Y;Использование функций - друзей классаclass X {int a;friend void fff (const X*, int); // здесь нет this !public:void mmm (int);};void fff (const X* p, int i) {p -> a = i;}void X::mmm (int i) {a = i;}void f () {X obj;fff (&obj, 10);obj.mmm (10);}Свойства друзей классаДружба не обладает ни наследуемостью, ни транзитивностью.Примеры:class A {friend class B;int a;};class B {friend class C;};class C {void f (A* p) {p -> a++; // ошибка, нет доступа к закрытым членам класса А}};class D: public B {void f (A* p) {p -> a++; // ошибка, нет доступа к закрытым членам класса А}};Преимущества использования друзей класса1.
Эффективность реализации ( можнообходить ограничения доступа,предназначенные для обычныхпользователей).2. Функция-друг нескольких классов позволяетупростить интерфейс этих классов.3. Функция-друг допускает преобразованиесвоего первого параметра-объекта, а методкласса - нет.Перегрузка операций• Для перегрузки встроенных операций С++используется ключевое слово operator.• Перегружать операцию можно с помощью- функции-члена,- функции-друга,- обычной функции (что менее эффективно).• Нельзя перегружать:‘.’ , ‘::’ , ‘?:’ , ‘.*’ , sizeof, и typeid !!!Пример 1.class complex {double re, im;public:complex (double r = 0, double i = 0) {re = r;im = i;}complex operator+ (const complex & a) {complex temp (re + a.re, im + a.im);return temp;}...
//(*) operator double () { return re; } – функция преобразования};int main () {complex x (1, 2), y (5, 8), z;double t = 7.5;z = x + y; // O.K. – x.operator+ (y);z = z + t; // O.K. – z.operator+ (complex (t)); если есть (*), то// неоднозначность: '+' - double или перегруженныйz = t + x; // Er.! – т.к.
первый операнд по умолчанию – типаcomplex.}Пример 2.class complex {double re, im;public:complex (double r = 0, double i = 0) {re = r;m = i;}friend complex operator+ (const complex & a, const complex & b);...};complex operator+ (const complex & a, const complex & b) {complex temp (a.re + b.re, a.im + b.im);return temp;}int main () {complex x (1, 2), y (5, 8), z;double t = 7.5;z = x + y; // O.K. – operator+ (x, y);z = z + t; // O.K. – operator+ (z, complex (t));z = t + x; //O.K. – operator+ (complex (t), x);}Пример 3.class complex {double re, im;public:friend complex operator * (const complex & a, double b);...};complex operator * (const complex & a, double b) {complex temp (a.re * b, a.im * b);return temp;}int main () {complex x (1, 2), z;double t = 7.5;z = x * t;// O.K.
– x.operator* (t);z = t * x;// Er.! т.к. нет функции преобразования x --> double, но// если бы была, была бы неоднозначность:// * - из double или из complex}В таких случаях обычно определяют еще одного друга с профилем:complex operator * (double b, const complex & a);Замечания- n-местные операции перегружаютсяa) методом с (n-1) параметром,b) функцией-другом или обычной функцией с nпараметрами;- в любом случае сохраняется приоритет,ассоциативность и местность операций;- операции= , [ ] , ( ) и ->можно перегрузить только нестатическимиметодами класса, что гарантирует, что первымоперандом будет сам объект, к которомуоперация применяется;Особенности перегрузки операций ++ и -complex x;префиксная ++:++ x; ~ x.operator ++ ();complex & operator ++ () {re = re + 1;im = im + 1;return *this;}постфиксная ++:x ++; ~ x.operator ++ (0);complex operator ++ (int) {complex c = * this;re = re + 1;im = im + 1;return c;}Пример перегрузки операции «( )» и операции вывода «<<»class Matrix {double M [ 3 ] [ 3 ];public:Matrix ();double & operator ( ) (int i, int j) {return M [ i ] [ j ];}friend ostream & operator << (ostream & s, const Matrix & a) {for (int i = 0; i < 3 ; i ++) {for (int j = 0; j < 3; j ++)s << a (i, j) << ' ';s << endl;}return s;}};.