Локальные и вложенные классы

В С++ поддерживается 2 области видимости: области видимости файла, локальная область видимости и область видимости класса. В то же время класс может быть определен внутри некоторого блока или функции, т.е. иметь локальную область видимости. В этом случае имя класса видно только в этой локальной области видимости.

void f()

{

//...

class X

{

...

}

X s2;

}

X s3; //ошибка

Локальное описание класса видно только в той области видимости, в которой этот класс описан.

void f2()//локальные переменные блока, в котором описан класса не видим

{ double x,y;

class X

{

...//x,y не видимы

}

]

Все методы локального класса должны быть встраиваемые.

Вложенность

Класс можно определить внутри другого класса. В этом случае внутренний класс называется вложенным. Современный стандарт С++ распространяет спецификацию доступа не только на данные, но и на имена вложенных классов. Области видимости и вложенность позволяет локально скрывать имена и выделять ресурсы. Очень часто бывает такая ситуация, что класс нужен как часть реализации некой большей конструкции.

Приведем программу, в которой реализуется класс, реализующий стек указателей на строки. Вложенные классы – указатели на стек.

class StrStack

{

class Link

{

class xste;

Link *next;

public:

Link(char *.ste,Link *_next):str(_str),next(_next)

{}//список инициализации

char * GetStr();//описание находится вне класса

Link *GetNext {return next;}

};

Link *head;

public:

StrSrack():head(0){}

~StrStack();

void Add(char *s);

char* Get();

int Empty() const {return !head;}

StrStack &operator+(char *str)

{

Add(str);

return *this;

}

};

 

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

inline char* StrStack::Link::GetStr()

{

return str;

}

 

//описание методов внешнего класса

StrStack::~StrStack()

{

while(!Empty())

{

Get();

}

}

 

void StrStack:: Add(char *str)

{

Link *p=new Link(str,head);

head =p;

}

 

char *StrStack:: Get()

{

if(!head) return “Пустой стек”;

char *str=head->getstr();

Link *p=head;

head=head->getnext();

delete p;

}

////

void main()

{

StrStack s;

s.Add(“Маша”);

s.Add(“Саша”);

s+”Даша”-“Паша”;

...

while(!s.Empty())

return s.get();

}


 

Специальный вид методов класса - конструкторы и деструкторы.

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

class Y

{

public:

int x,y;

};

У такого класса имеется 2 конструктора: конструктор по умолчанию, который не имеет параметров и мог бы быть описан как Y::Y(){}. Второй конструктор называется конструктором копий и мог бы быть описан в определении класса следующим образом: Y (const &y); . Он используется при создании объекта с инициализацией объекта того же типа. Кроме того конструктор копий используется при инициализации формального параметра функции в случае передачи ей объекта по значению, а так же при возврате из функции по оператору return.

При передачи ссылок и указателей конструктор копий не используется. Только когда речь идет возврате и передачи по значению. Неявный конструктор копий обеспечивает простое копирование одного объекта во второй. Такое копирование называется поверхностным (shallow copy).

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

Конструктор копирования-это специальное вид конструктора, получающий в качестве единственного параметра ссылку на объект этого же класса

Конструктор по умолчанию-это конструктор, вызывающийся без параметров

Деструкор-это особый вид метода, применяющийся для освобождения памяти