Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Билеты по ООП.doc
Скачиваний:
4
Добавлен:
14.04.2019
Размер:
596.48 Кб
Скачать

22. Массивы объектов

Можно создавать массивы объектов точно так же, как создаются массивы данных других типов.

Инициализация массивов объектов

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

Пример

#include <iostream>

using namespace std;

class cl{

int h;

int i;

public:

cl(int j, int k) {h=j; i=k;}

int get_i() {return i; }

int get_h() {return h;}

};

int main()

{

cl ob[3] = {

cl(1, 2),

cl(3, 4),

cl(5, 6)

};

int i;

for (i=0; i<3; i++) {

cout << ob[i].get_h();

cout << “, “;

cout << ob[i].get_i() << “\n”;

}

return 0;

}

Для создания неициализированных массивов необходимо иметь конструктор без параметров.

23. Указатели на объекты

В С++ можно получить доступ к объекту как непосредственно, так и используя указатель на объект.

Пример

#include <iostream>

using namespace std;

class P_example {

int num;

public:

void set_num(int val){num=val;}

void show_num();

};

void P_example::show_num()

{

cout << num << “\n”;

}

int main()

{

P_example ob, *p;

ob.set_num(1);

ob.show_num();

p=&ob;

p->show_num();

return 0;

}

24. Указатель this

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

тип_класса *.

Пример.

class simple

{

public:

simple();

void greet() { cout<<“ Hello!”;};

};

simple::simple()

{

greet(); // вызов

this>greet(); // функции

(*this).greet(); // greet()

}

Т.к. функции-элементы могут обращаться ко всем элементам класса просто по имени, в основном указатель this используется для возврата указателя (return this) или ссылки (return *this) на подразумеваемый объект.

25. Перегрузка операторов

С++ поддерживает перегрузку операторов. За небольшими исключениями большинство операторов С++ могут быть перегружены, в результате чего они получат специальное значение по отношению к определённым классам. Например, класс, определяющий связанный список, может использовать оператор + для того, чтобы добавлять объект к списку. Другой класс может использовать оператор + совершенно иным способом. Когда оператор перегружен, ни одно из его исходных значений не теряет смысла. Просто для определённого класса объектов определён новый оператор. Поэтому перегрузка оператора + для того чтобы обрабатывать связный список, не изменяет его действия по отношению к целым числам.

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

Для того, чтобы перегрузить оператор, необходимо определить, что именно означает оператор по отношению к тому классу, к которому он применяется. Общая форма записи функции-оператора для случая, когда она является членом классом класса, имеет вид:

тип имя_класса::operator#(список аргументов)

{

// действия, определённые применительно к классу

}

Здесь перегруженный оператор подставляется вместо символа #, а тип задает тип значений, возвращаемых оператором. Для того, чтобы упростить использование перегруженного оператора в сложных выражениях, в качестве возвращаемого значения часто выбирают тот же самый тип, что и класс, для которого перегружается оператор.

Пример

Листинг 1

Создаётся класс three_d, содержащий координаты объекта в трёхмерном пространстве. Следующая программа перегружает операторы + и = для класса three_d.

#include <iostream>

using namespace std;

class three_d {

int x,y,z;

public:

three_d operator+(three_d t);

three_d operator=(three_d t);

void show();

void assign(int mx, int my, int mz);

};

//

three_d three_d::operator+(three_d t)

{

three_d temp;

temp.x=x+t.x;

temp.y=y+t.y;

temp.z=z+t.z;

return temp;

}

//

three_d three_d::operator=(three_d t)

{

x=t.x;

y=t.y;

z=t.z;

return *this;

}

//

void three_d::show()

{

cout << x <<",";

cout << y <<",";

cout << z <<"\n";

}

//

void three_d::assign(int mx, int my, int mz)

{

x=mx;

y=my;

z=mz;

}

int main()

{

three_d 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();

return 0;

}

Если рассмотреть эту программу внимательно, может вызвать удивление, что обе функции-оператора имеют только по одному параметру, несмотря на то, что они перегружают бинарный оператор. Это связано с тем, что при перегрузке бинарного оператора с использованием функции-члена ей передаётся явным образом только один аргумент. Вторым аргументом служит указатель this, который передаётся ей неявно. Так, в строке

temp.x = x+t.x;

x соответствует this->x, где x ассоциировано с объектом, который вызывает функцию-оператор. Объект, стоящий справа от знака операции, передаётся функции.

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

Тщательно проанализируем, как работает программа из листинга 1, начиная с перегруженного оператора +. Когда два объекта типа three_d подвергаются воздействию оператора +, значения их соответствующих координат складываются, как показано в функции operator+(), ассоциированной с данным классом. Обратим внимание на то, что функция не модифицирует значений операндов. Вместо этого она возвращает объект типа three_d, содержащий результат выполнения операции.

Другим ключевым моментом перегрузки оператора сложения является то, что он возвращает объект типа three_d. Хотя функция может иметь в качестве значения любой допустимый тип языка С++, то, что она возвращает объект типа three_d, позволяет использовать оператор + в более сложных выражениях, таких как a+b+c. Здесь a+b создаёт результат типа three_d. Это значение затем прибавляется к c.

В противоположность оператору +, оператор присваивания модифицирует свои аргументы. Поскольку функция operator=() вызывается объектом, стоящим слева от знака равенства, то именно этот объект модифицируется. Однако даже оператор присваивания обязан возвращать значение, поскольку оператор присваивания порождает величину, стоящую с правой стороны равенства. Так, для того чтобы выражение следующего вида

a = b = c = d;

было допустимым, необходимо, чтобы оператор operator=() возвращал объект, на который указывает this и который будет объектом, стоящим с левой стороны. Если сделать таким образом, то можно выполнить множественное присваивание.

Следующие операторы не могут быть перегружены:

. :: .* ?