Если коротко, то: объявление знакомит с новым именем; определение создает объект, названный этим именем. Объявлений может быть сколько угодно, определение может быть только одно.
Объявление вводит новый идентификатор и описывает его тип. Например, в объявлении
extern int x;
модификатор extern
сообщает компилятору, что где-то есть целочисленная переменная x
. При этом компилятор не выделяет память для хранения x
, а только добавляет ее к списку переменных которые вы можете использовать.
Определение создает сущность, отмеченную данным идентификатором. Так, память для x
будет выделена, когда в программе встретится строка
int x;
При этом объявлений может быть сколько угодно (например, extern int x;
может находится в заголовочном файле), а определение может быть только одно.
Примеры объявлений функций:
extern int g(int, int);
double f(int, double); // extern в объявлении функции можно опустить
и соответствующих им определений:
int g(int lhs, int rhs) { return lhs*rhs; }
double f(int i, double d) { return i+d; }
Для классов это выглядит так:
class Foo; // объявление
Foo* ptr; // это сработает
Foo foo; // это НЕ сработает
Объявление сообщает компилятору, что существует класс по имени 'Foo'
. Оно не говорит, как устроен этот класс (сколько он занимает места в памяти, какие у него поля). Теперь мы можем использовать указатели на Foo
, но не его экземпляры -- пока не известно как устроен Foo
, и сколько места нужно выделить в памяти под его экземпляры.
После определения класса
class Foo
{
public:
char* name;
int data;
}; // определение
Foo* ptr; // это сработает
Foo foo; // теперь и это сработает
// кроме того, мы получаем доступ к членам этого класса:
foo.data = 17;
мы знаем о нем достаточно, чтобы использовать его экземпляры.
Если коротко, то для классов class Foo;
-- объявление, а class Foo {};
-- определение.
Комментарии
comments powered by Disqus