13.1.5. Объявление и определение класса

13.1.5. Объявление и определение класса

О классе говорят, что он определен, как только встретилась скобка, закрывающая его тело. После этого становятся известными все члены класса, а следовательно, и его размер.

Можно объявить класс, не определяя его. Например:

class Screen; // объявление класса Screen

Это объявление вводит в программу имя Screen и указывает, что оно относится к типу класса.

Тип объявленного, но еще не определенного класса допустимо использовать весьма ограниченно. Нельзя определять объект типа класса, если сам класс еще не определен, поскольку размер класса в этом момент неизвестен и компилятор не знает, сколько памяти отвести под объект.

Однако указатель или ссылку на объект такого класса объявлять можно, так как они имеют фиксированный размер, не зависящий от типа. Но, поскольку размеры класса и его членов неизвестны, применять оператор разыменования (*) к такому указателю, а также использовать указатель или ссылку для обращения к члену не разрешается, пока класс не будет полностью определен.

Член некоторого класса можно объявить принадлежащим к типу какого-либо класса только тогда, когда компилятор уже видел определение этого класса. До этого объявляются лишь члены, являющиеся указателями или ссылками на такой тип. Ниже приведено определение StackScreen, один из членов которого служит указателем на Screen, который объявлен, но еще не определен:

class Screen; // объявление

class StackScreen {

int topStack;

// правильно: указатель на объект Screen

Screen *stack;

void (*handler)();

};

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

class LinkScreen {

Screen window;

LinkScreen *next;

LinkScreen *prev;

};

Упражнение 13.1

Пусть дан класс Person со следующими двумя членами:

string _name;

string _address;

и такие функции-члены:

Person( const string &n, const string &s )

: _name( n ), _address( a ) { }

string name() { return _name; }

string address() { return _address; }

Какие члены вы объявили бы в секции public, а какие – в секции private? Поясните свой выбор.

Упражнение 13.2

Объясните разницу между объявлением и определением класса. Когда вы стали бы использовать объявление класса? А определение?