Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Лафоре Р. -> "Объектно-ориентированное программирование в С++" -> 228

Объектно-ориентированное программирование в С++ - Лафоре Р.

Лафоре Р. Объектно-ориентированное программирование в С++ — М.: Питер, 2004. — 992 c.
Скачать (прямая ссылка): obektnoorentprogramm2004.djvu
Предыдущая << 1 .. 222 223 224 225 226 227 < 228 > 229 230 231 232 233 234 .. 341 >> Следующая


Определение класса содержит определения или объявления всех его членов:

class someClass //определение класса

{

private:

int memVar: //определение компонентной переменной

public:

int memFunc(int. int): //объявление метода

}:

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

Объявление класса лишь говорит о том, что то или иное имя принадлежит данному классу. В нем ничего не сообщается компилятору о компонентах класса, class someClass; //объявление класса Межфайловое взаимодействие 605 .

Не путайте определение класса с определением (созданием) объекта класса: someClass anObJ:

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

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

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

//объявление

extern int someVar: //видя объявление.

someVar - 3: // компилятор может обработать это.

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

//объявление

int someFunc(int. int): //видя объявление.

varl = someFunc(var2,var3): //компилятор может обработать это.

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

//определение

class someClass: //видя определение, компилятор

(

private:

int memVar; public: int memFunc(int, int):

}:

someClass someObj: //может обработать это

vi - someObj.memFunc(v2. v3): //и это

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

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

Заголовочные файлы

Как отмечалось в главе 2, директива ffindude работает, как функция ВСТАВИТЬ в текстовых редакторах, то есть указанный после этой директивы файл просто 606

Глава 13. Многофайловые программы

вставляется в исходный. В очень многих примерах мы видели включения библиотечных файлов типа I0STREAM.

Можно также и самостоятельно написать заголовочный файл и включить его в свою программу.

Общая информация

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

Конечно, каждый элемент программы должен быть определен в каком-то месте. Например, переменная и функция объявлены в fileH.h, а определены в fileA.cpp. Код из файла fileB.cpp может использовать эти элементы без дополнительных объявлений.

//fileH.h

extern int gloVar; //объявление переменной

int gloFuncCint): //объявление функции

//fileA.cpp

int gloVar; //определение переменной

int gloFuncOnt п) //определение функции

{ return п: }

//fileB.cpp !include "fileH.h"

gloVar - 5; //работа с переменной

int gloVraB=gloFunc(gloVar): //работа с функцией

Помните, что в заголовочном файле можно хранить объявления, но не определения переменных или функций. При использовании этого файла в других (если только данные не static или const) такая оплошность приведет к ошибке компоновщика «повторные определения».

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

//fileH.h

class someClass: //определение класса

{

private:

int mernVar; public: int memFunc(int. int):

}:

//fileA.cpp finclude "fileH.h"

int mainO { Межфайловое взаимодействие 607 .

someClass Objl; //создание обьекта

int varl - 0bjl.memFunc(2. 3); //работа с объектом }

//fileB.cpp !include "fileH.h"

int funcO {

someClass 0bj2; //создание обьекта

int var2 - 0bj2.memFuncC4, 5); //работа с обьектом }

А что бы, интересно, было, если бы вместо использования заголовочного файла мы просто вставили этот текст с определением класса в каждый из файлов? Ничего бы страшного, на самом деле, не произошло, просто каждое маленькое изменение в классе пришлось бы производить во всех этих файлах. Это отняло бы массу времени, да еще и наверняка привело бы к опечаткам.
Предыдущая << 1 .. 222 223 224 225 226 227 < 228 > 229 230 231 232 233 234 .. 341 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100