1Параметры_Аргум_Ссылки_2

advertisement
Параметры и аргументы функции
Передача объекта в функцию
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();
Download