Параметры и аргументы функции Передача объекта в функцию class X { public: X () {cout<<“Конструктор\n”;} ~ X () {cout<<“Деструктор\n”;} }; void f (X obj) {cout<<“Функция\n”;} int main (void) { X obj; f (obj); … } Результат работы: Конструктор Функция Деструктор Деструктор Возврат объекта из функции class X { public: X () {cout<<“Конструктор\n”;} ~ X () {cout<<“Деструктор\n”;} }; X f () { X obj; cout<<“Функция\n”; return obj; } int main (void) { X obj_main; obj_main=f (); … } Результат работы: Конструктор Конструктор Функция Деструктор Деструктор Деструктор Инициализация одного объекта другим при создании class X { public: X () {cout<<“Конструктор\n”;} ~ X () {cout<<“Деструктор\n”;} }; int main (void) { X obj_1; X obj_2 = obj_1; // побитовое // копирование //X obj_2 (obj_1); то же //действие … } Результат работы: Конструктор Деструктор Деструктор . 2 способа решения проблемы: - передача объекта по ссылке или по указателю; - создание особого типа конструкторов – конструкторов копирования Указатели и ссылки на объекты Инициализация: int a = 10; int *p = a; int &ref = a; Обращение: cout<<a; cout<<*p; cout<<ref ; class X { int a; public: void f1 (int i) {x=i;} // по значению void f2 (int *i) {x=*i;} // по указателю void f3 (int &i) {x=i;} // по ссылке }; Важно отличать ссылки от оператора взятия адреса &. Оператор взятия адреса используется для уже созданного объекта с целью получить его адрес (то есть адрес области памяти, где хранятся значения), а ссылка это только задание альтернативного имени объекта Отличие указателя от ссылки в том, что получить само значение переменной, на которую указывает указатель, можно только выполнив операцию разыменовывания * В качестве результата первого указания не могут быть выполнены никакие арифметические вычисления, приведения типов, взятия адреса и т.п. После создания ссылки ее нельзя перевести на другой объект; в таких случаях говорят, не может быть переопределена. Это часто делают с указателями. Ссылки не могут быть null (т.е.указывать в никуда) Передача объекта в функцию class A { int i; public: void set_i (int x) {i = x;} void out_i () {cout<<i<<“ ”;} }; Использование в качестве параметра Использование в качестве параметра указателя ссылки void f (А &х) void f (А *х) { { x->out_i (); x->out_i (); x->set_i (100); x->set_i (100); x->out_i (); x->out_i (); } } int main (void) { int main (void) { A obj; obj.set_i (10); f(obj); obj. out_i (); A obj; obj.set_i (10); f(& obj); obj. out_i (); } } Конструктор копирования или конструктор копии имя_класса (const имя_класса & obj) ClassName r () { ClassName o; cout<<"Function r!!!\n"; return o; } { ... // тело конструктора } ПРИМЕР class ClassName { public: ClassName ( ) { cout << "ClassName!!!\n“ ;} ClassName ( ClassName & obj ) { cout << "Copy ClassName!!!\n“; } ~ClassName ( ) { cout << "~ClassName!!!\n“;} void f ( ClassName o ) { cout<<"Function f!!!\n“;} void main() { // инициализация одного объекта другим ClassName c1; ClassName c2=c1; // передача объекта в функцию ClassName a; f(a); //возврат объекта из функции r(); } Конструктор копирования или конструктор копии Результат работы программы: // создался объект с1 ClassName!!! // инициализация объекта с2 объектом с1 Copy ClassName!!! // создался объект а ClassName!!! // передача а в функцию по значению // создалась копия о Copy ClassName!!! // отработала функция f Function f!!! // уничтожилась копия o ~ClassName!!! // создался объект o // внутри функции r ClassName!!! // отработала функция r Function r!!! // возврат из функции // создалась копия объекта о Copy ClassName!!! // уничтожился объект o ~ClassName!!! // уничтожилась его копия ~ClassName!!! // уничтожился объект а ~ClassName!!! // уничтожился объект с2 ~ClassName!!! // уничтожился объект с1 ~ClassName!!! Перегрузка операций Основная форма функции-операции, являющейся функцией-элементом класса: тип имя класса : : операция # ( список аргументов ) { // операторы, определяющие действия } Здесь # - конкретный знак операции. Часто возвращаемое значение того же типа, что и класс. Задача: Класс vector - определяет трёхмерный вектор в евклидовом пространстве. Операция сложения двух векторов = сложение соответствующих координат В программе перегружаются операции «+» «++» и «=» относительно класса vector . Перегрузка операций class vector { int x,y,z; public: vector operator+(vector t); vector operator=(vector t); vector operator++(); void show(){cout<<"x = "<<x<<" | y= "<<y<<"| z = "<<z<<"\n"; }; void assign (int mx, int my, int mz ) {x=mx; y=my; z=mz; } }; vector vector::operator+(vector t) { vector temp; temp.x = x+t.x; temp.y = y+t.y; temp.z = z+t.z; return temp; }; vector vector::operator=(vector t) { x=t.x; y=t.y; z=t.z; return *this; }; vector vector::operator++() { x++; y++; z++; return *this; }; vector vector::operator++(int) { ++x; ++y; ++z; return *this; }; Перегрузка операций int main() { vector a,b,c; a.assign(1,2,3); b.assign(10,10,10); a.show(); b.show(); c=a+b; c.show(); c=a+b+c; c.show(); c=b=a; c.show(); b.show(); //c++; c.show(); system("pause"); return 0; } Результат работы программы: x=1 y=2 z=3 x=10 y=10 z=10 x=11 y=12 z=13 x=22 y=24 z=26 x=1 y=2 z=3 x=1 y=2 z=3 x=2 y=3 z=4 Перегрузка операций vector vector::operator++() { x++; y++; z++; return *this; }; vector vector::operator+(vector t) { vector temp; temp.x = x+t.x; temp.y = y+t.y; temp.z = z+t.z; return temp; }; Один аргумент неявно передаётся с использованием this – указателя. Строка: temp.x = x+t.x; аналогична строке: temp.x = this ->x + t.x; Здесь, this ассоциируется с объектом, предшествующим знаку операции. Объект справа от знака операции передаётся как параметр. Перегруженные функции (overload functions) // прототипы функций int sqr_it (int i); double sqr_it (double d); long sqr_it (long l); int main() { int i=7; double d=1.1; long l=20; // аргумент функции – константа cout<<sqr_it (10)<<“\n”; cout<<sqr_it (10.1)<<“\n”; cout<<sqr_it (70000)<<“\n”; return 0; } int sqr_it (int i) { cout<<“Аргумент int”<<“\n”; return i*i; } double sqr_it (double d) // аргумент функции – переменная { cout<<“Аргумент double ”<<“\n”; //заданного типа return d*d; } cout<<sqr_it (i)<<“\n”; cout<<sqr_it (d)<<“\n”; long sqr_it (long l) cout<<sqr_it (l)<<“\n”; { cout<<“Аргумент long ”<<“\n”; return l*l; } Перегруженные функции Стандартные функции в языке С: int sqr_it (long i); long sqr_it (long l); atoi(); atof(); atol(); sqr_it (70000); - преобразуют строку цифр во внутренний формат чисел типа int, double, long В C++: Одно имя функций с разными типами аргументов: atonum();