Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lutsik_Yu_A_Obektno_orientir_programmir_na_yaz.pdf
Скачиваний:
64
Добавлен:
11.05.2015
Размер:
4.33 Mб
Скачать

}

int main()

{ NAME::n1=3;

 

// n1=4;

error

'n1' надо указывать полностью NAME::n1

 

// n2=5;

error

'n2' : undeclared identifier

 

 

 

// int n2;

следующая строка приводит к ошибке

 

 

using NAME::n2;

// далее n2 доступно

 

 

 

n2=6;

 

 

 

 

 

 

cout <<NAME::n1<<" "<< n2 << endl; // результат

3 6

Р

 

{ NAME::n1=7;

 

 

 

n2=8;

 

 

 

 

 

cout <<NAME::n1<<" "<< n2 << endl;// результат

7 8

 

}

 

 

 

 

 

 

 

 

И

}

return 0;

 

 

 

 

 

 

 

В результате выполнения программы получим:У

 

3

6

 

 

Г

 

 

7

8

 

 

 

 

Объявление using добавляет определенноеаБимя в текущую область дейст-

вия. В примере к переменной n2 можно обр щаться без указания принадлежно- сти классу, а для n1 необходимо полное имя. Объявление using обеспечивает более подробное управление и нами, переносимыми в пространство имен. Это

 

 

 

 

т

 

и есть ее основное отличие от дирктивы, которая переносит все имена про-

странства имен.

про

ме

 

 

Внесение в локальную область (блок) имени, для которого выполнено яв-

ное объявление (и на б р ), является серьезной ошибкой.

 

 

и

 

 

 

 

3.13.4. Псевд н м прос ранства имен

 

Псевдон м

странства имен существует для того, чтобы назначить дру-

 

 

л

 

 

 

 

гое имя именованному пространству имен.

 

б}

 

 

 

// пространство имен

 

namespace spisok_name_peremen

 

{ int n1=1;

 

 

 

 

и

 

 

 

 

 

Б

. . .

 

 

 

 

NAME = spisok_name_peremen;

// псевдоним пространства имен

 

Пространству имен spisok_name_peremen назначается псевдоним NAME. В этом случае результат выполнения инструкций:

cout <<NAME::n1<< endl;

cout<< spisok_name_peremen::n1<<endl;

будет одинаков.

3.14. Практические приемы ограничения числа объектов класса

Иногда для эффективной работы желательно ограничивать число объек-

61

тов. Пусть, например, разрабатывается класс для принтера. При этом в системе необходимо при множестве клиентов (заданий, объектов класса PrntJob) иметь только один объект (принтер, объект класса Printer). Это может быть достигнуто инкапсуляцией объекта «принтер» в одну из функций. Все конструкторы класса Printer должны быть закрытые и могут быть вызваны только из открытых мето- дов класса Printer или методов, дружественных этому классу. Кроме того, соз- даваемый объект является статическим, что исключает возможность его по- вторного создания.

#include <iostream>

 

 

 

 

 

 

 

 

 

 

Р

 

 

 

 

 

 

 

 

 

 

 

using std::cout;

 

 

 

 

 

 

 

 

 

 

И

using std::endl;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

#include <string>

 

 

 

 

 

 

 

 

 

 

 

 

using std::string;

 

 

 

 

 

 

 

 

 

 

 

 

class PrntJob;

 

 

// предварительное объявление

 

 

 

class Printer

 

 

 

// класс «принтер»

 

Г

 

 

 

 

 

Б

У

 

{ Printer(){}

 

 

 

 

 

 

 

 

 

 

Printer(const Printer& obj){};

 

 

 

 

 

 

 

 

public:

 

 

 

 

 

 

 

да

 

 

 

 

 

void Job(PrntJob&);

 

//

функция выво з д ния

 

 

 

 

friend Printer& Print();

//

 

 

к

 

 

 

 

 

 

функция возвр щ ет ссылку

 

 

 

};

 

 

 

// на объ т «принтер»

 

 

 

 

class PrntJob

 

 

//

класс «задание»

 

 

 

 

 

{ string str;

 

 

 

 

т

 

 

 

 

 

 

 

public:

 

 

о

е

 

 

 

 

 

 

};

 

 

 

 

 

 

 

 

 

 

 

void get(const string str)

// инициализация объекта «задание»

 

 

{this->str=str;}

и

// в зврат ссылки на текущее задание

 

 

string& put(){return str;}

 

 

 

л

 

 

 

 

 

 

 

 

 

 

 

void Printer::Job(PrntJob& obj)

 

 

 

 

 

 

 

 

{cout<<obj.put()<<endl;

 

 

 

 

 

 

 

 

 

}

и

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Б

 

 

 

 

 

 

 

 

 

 

 

 

 

Printer& Print()б

 

 

// статический объект «принтер»

 

 

 

{ static Printer pr;

 

 

 

 

 

}

return pr;

 

 

 

// возврат ссылки на объект «принтер»

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

int main()

 

 

 

 

 

 

 

 

 

 

 

 

 

{ PrntJob ob1,ob2;

 

 

 

 

 

 

 

 

 

 

 

 

ob1.get("задание 1");

 

 

 

 

 

 

 

 

 

 

 

ob2.get("задание 2");

 

 

 

 

 

 

 

 

 

 

 

// cout<<&Print()<<endl;

// выводится адрес объекта «принтер»

 

 

Print().Job(ob1);

 

 

 

 

 

 

 

 

 

 

 

 

62

// cout<<&Print()<<endl; Print().Job(ob2);

}

В результате работы программы получим: задание 1 задание 2

Если при этом выводить адреса объекта «принтер», создаваемого для вы- вода первого и второго задания, то получим одинаковые адреса. Следовательно,

можно утверждать, что в функции Print создается единственный объект для вы-

вода всех заданий.

 

 

 

 

 

 

 

 

Р

 

 

 

 

 

 

 

 

 

 

Можно поступить

иначе,

сделав

функцию

Print статическим членом-

 

 

 

 

 

 

 

 

 

 

 

 

И

функцией класса Printer. Это также исключает необходимость использования

friend-механизма для функции Print.

 

 

 

 

 

class PrntJob;

 

 

// предварительное объявление

 

 

class Printer

 

 

// класс «принтер»

У

 

 

{ Printer(){}

 

 

 

 

 

 

Г

 

 

 

Printer(const Printer& obj){};

 

 

 

 

public:

 

 

 

 

 

 

 

Б

 

 

 

 

void Job(PrntJob&);

 

 

 

а

 

 

 

 

 

// функция вывода задания

 

 

 

static Printer& Print();

 

 

к

 

 

 

 

 

 

// созд ние ст тического объекта «принтер»

 

 

. . .

 

 

 

 

 

 

 

 

 

 

 

};

 

 

т

 

 

 

 

 

 

 

class PrntJob

//

класс «задание»

 

 

 

{ . . .

о

е

 

 

 

 

 

};

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

void Printer::Job(PrntJob& obj)

 

 

 

 

 

{cout<<obj.put()<<endl;

 

 

 

 

 

 

 

 

}

 

л

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

б}

 

 

 

 

 

 

 

 

 

 

 

Printer&иPrinter::Print()

 

 

 

 

 

 

 

 

{ static Printer pr;

 

 

// статический объект «принтер»

 

и

 

 

 

 

// возврат ссылки на объект «принтер»

Б

 

return pr;

 

 

 

int main()

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

{ PrntJob ob1,ob2; ob1.get("задание 1"); ob2.get("задание 2");

Printer::Print().Job(ob1); // вызов объекта принтер для объекта задание

Printer::Print().Job(ob2);

}

Вопросы и упражнения для закрепления материала

63

1.В чем разница между struct, class и union?

2.Что такое указатель this? Приведите пример использования этого указателя.

3.Какова основная форма конструктора копирования и когда он вы- зывается?

4.Откомпилируется ли следующая программа, если да, то что она выве- дет на экран?

#include <iostream> using namespace std; void f()

{ class A

 

 

 

 

 

 

 

Р

 

{ public:

 

 

 

 

 

 

 

 

void g() {cout << "A::g"<<endl;}

 

У

 

};

 

 

 

 

 

 

Г

И

 

A a;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

}

a.g();

 

 

 

 

 

Б

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

int main()

 

 

 

 

 

программы, если да, то

5. Возникнут ли ошибки при компиляциианнойд

{

f();

 

 

 

 

 

 

 

 

 

}

return 0;

 

 

 

 

 

 

 

 

почему, если нет, то что выведет программакна э ран:

 

 

 

#include <iostream>

 

 

е

 

 

 

using namespace std;

 

 

 

 

 

 

т

 

 

 

int I1=1;

 

 

 

 

 

 

 

int I2=2;

 

 

 

 

 

 

 

class A

 

 

 

о

 

 

 

 

{

const int& i;

и

 

 

 

 

 

public:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

A():i(I1){};

 

 

 

 

 

 

 

 

 

 

л

 

 

 

 

 

 

 

friend void f(A&);

 

 

 

 

 

 

};

 

б

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

void f(A& a)

 

 

 

 

 

 

 

 

 

и

 

 

 

 

 

 

 

 

{ a.i = I2;}

 

 

 

 

 

 

 

 

Бint main()

 

 

 

 

 

 

 

 

{ A a; f(a);

cout<<I1<<I2; return 0;

}

64

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]