Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Cpp_Страуструп.doc
Скачиваний:
17
Добавлен:
03.05.2015
Размер:
3.2 Mб
Скачать

5.4.2 Уточнение имени члена

Иногда полезно делать явное различие между именами членов классов

и прочими именами. Для этого используется операция :: (разрешения

области видимости):

class X {

int m;

public:

int readm() const { return m; }

void setm(int m) { X::m = m; }

};

В функции X::setm() параметр m скрывает член m, поэтому к члену

можно обращаться, только используя уточненное имя X::m. Правый

операнд операции :: должен быть именем класса.

Начинающееся с :: имя должно быть глобальным именем. Это особенно

полезно при использовании таких распространенных имен как read, put,

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

обозначать ими же функции, не являющиеся членами.

Например:

class my_file {

// ...

public:

int open(const char*, const char*);

};

int my_file::jpen(const char* name, const char* spec)

{

// ...

if (::open(name,flag)) { // используется open() из UNIX(2)

// ...

}

// ...

}

5.4.3 Вложенные классы

Описание класса может быть вложенным. Например:

class set {

struct setmem {

int mem;

setmem* next;

setmem(int m, setmem* n) { mem=m; next=n; }

};

setmem* first;

public:

set() { first=0; }

insert(int m) { first = new setmem(m,first); }

// ...

};

Доступность вложенного класса ограничивается областью видимости

лексически объемлющего класса:

setmem m1(1,0); // ошибка: setmem не находится

// в глобальной области видимости

Если только описание вложенного класса не является совсем простым,

то лучше описывать этот класс отдельно, поскольку вложенные описания

могут стать очень запутанными:

class setmem {

friend class set; // доступно только для членов set

int mem;

setmem* next;

setmem(int m, setmem* n) { mem=m; next=n; }

// много других полезных членов

};

class set {

setmem* first;

public:

set() { first=0; }

insert(int m) { first = new setmem(m,first); }

// ...

};

Полезное свойство вложенности - это сокращение числа глобальных имен,

а недостаток его в том, что оно нарушает свободу использования

вложенных типов (см. $$12.3).

Имя класса-члена (вложенного класса) можно использовать вне

описания объемлющего его класса так же, как имя любого другого

члена:

class X {

struct M1 { int m; };

public:

struct M2 { int m; };

M1 f(M2);

};

void f()

{ M1 a; // ошибка: имя `M1' вне области видимости

M2 b; // ошибка: имя `M1' вне области видимости

X::M1 c; // ошибка: X::M1 частный член

X::M2 d; // нормально

}

Отметим, что контроль доступа происходит и для имен вложенных

классов.

В функции-члене область видимости класса начинается после

уточнения X:: и простирается до конца описания функции. Например:

M1 X::f(M2 a) // ошибка: имя `M1' вне области видимости

{ /* ... */ }

X::M1 X::f(M2 a) // нормально

{ /* ... */ }

X::M1 X::f(X::M2 a) // нормально, но третье уточнение X:: излишне

{ /* ... */ }