Forward type declarations

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Forward type declarations

Сообщение trifon » 13.02.2007 23:30:38

Допустимо ли подобное объявление?
Код: Выделить всё
type TVector3 = class;
.....
type
   TVector3 = class
.....
   end;

Собирается без предуприждений, однако в мануале описания этого я не нашёл.

Также возможноли сделать два unit с циклическими зависимостями, так чтобы оба были видны в interface друг друга.
В c++ это делается так -

fileA.h
Код: Выделить всё
class B; //Forward
class A {
......
   void use( B arg );
};


fileB.h
Код: Выделить всё
class A; //Forward
class B {
......
   void use( A arg );
};

fileA.cpp
Код: Выделить всё
#include"fileB.h"

fileB.cpp
Код: Выделить всё
#include"fileA.h"

Однако в fpc подобное не проходит
Error: Forward type not resolved "TMatrix4"
trifon
постоялец
 
Сообщения: 135
Зарегистрирован: 24.12.2006 12:08:35

Сообщение Sergei I. Gorelkin » 14.02.2007 00:54:02

В пределах одного модуля ранние объявления допустимы. Это должно быть документировано...

А циклические зависимости между модулями - увы. Только между interface и implementation. У Паскаля каждый модуль имеет собственное пространство имен. Добавьте в свой пример на C++ в каждый файл свой namespace - он тоже не соберется.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Cheb » 15.02.2007 15:33:59

Если создаёшь что-то грандиозное, с многими взаимозависимостями, то, ИМХО, лучше использовать Си-подход. Оформить как один гигантский модуль, разбитый на множество *.inc'ов, подключаемых через {$include ***}.

Так, почитай, вся RTL ФриПаскаля построена.

Или вот у меня, например: сложная перзистентная система - один модуль, состоящий из 29 файлов.
Иначе бы я в этом громадье просто запутался.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

Сообщение MylnikovDm » 16.02.2007 22:11:49

По поводу предварительных объявлений классов в Паскале не забывайте о том, что все предварительные объявления должны находится в одном блоке type (по крайней мере в Delphi это именно так, FPC пока не проверял). Если же между предварительным объявлением и полным объявлением вставить, например, блок const, то компилятор Delphi выдаёт ошибку.

Если уж очень надо передать класс внутрь процедуры или функции, то можно объявить его как класс предка, кторый виден из обоих модулей (в самом крайнем случае уйти на TObject), а уже в самой функции или процедуре сделать проверку и приведение к нужному типу через as или напрямую.
MylnikovDm
постоялец
 
Сообщения: 103
Зарегистрирован: 15.02.2007 21:26:10
Откуда: Челябинск

Сообщение trifon » 17.02.2007 17:02:38

Так оно и есть

Код: Выделить всё
type PMatrix4 = ^TMatrix4;
.....
type TMatrix4 = class
.....
end;


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

А такой вариант без проблем
Код: Выделить всё
type TMatrix4 = class;
.....
type TMatrix4 = class
.....
end;


Единственная проблема - это глюки форматирования в kde редакторе.
Я так и не понял правильно это или нет.

Нашёл это методом тыка, пытаясь сделать как в c++.
В чужом коде на паскале ничего подобного не встречал.
trifon
постоялец
 
Сообщения: 135
Зарегистрирован: 24.12.2006 12:08:35

Сообщение trifon » 17.02.2007 17:46:51

Посмотрел в исходниках fpc, а там море подобных объявлений.
Так что вопрос отпадает вот бы ещё глюки кдешного редактора побороть.
trifon
постоялец
 
Сообщения: 135
Зарегистрирован: 24.12.2006 12:08:35

Сообщение MylnikovDm » 18.02.2007 01:54:23

type PMatrix4 = ^TMatrix4;
.....
type TMatrix4 = class
.....
end;

Честно говоря, не могу представить зачем бы могло понадобиться подобное объявление. В чём состоит великий смысл делать указатель на TMatrix4? Экземпляры классов и так являются указателями.
MylnikovDm
постоялец
 
Сообщения: 103
Зарегистрирован: 15.02.2007 21:26:10
Откуда: Челябинск

Сообщение trifon » 18.02.2007 12:58:53

Код: Выделить всё
type
   PMatrix4 = ^TMatrix4;
   TMatrix4 = class
......
end;

Компилируется без предуприждений.
Значит авторы паскаля считают что это нужно.
В СИ указатель на указатель используется очень широко,
например как другая форма записи двумерного массива.
А вот двумерный массив как раз используют редко.
В C++ часто используется массив указателей на класс.
Так что при желании в СИ можно объявить указатель тройного и более порядка, хотя разбиратся в этом будет трудновато.
trifon
постоялец
 
Сообщения: 135
Зарегистрирован: 24.12.2006 12:08:35

Сообщение MylnikovDm » 18.02.2007 14:11:26

Компилируется без предуприждений.
Значит авторы паскаля считают что это нужно.

Авторы паскаля тут не причём. Синтаксис языка позволяет записать такую конструкцию, потому и должно компилироваться.

Так что при желании в СИ можно объявить указатель тройного и более порядка, хотя разбиратся в этом будет трудновато.

В паскале тоже можно объявить тройной и более указатель. Но флаг вам в руки потом подобную программу отлаживать.

Когда я написал о том, что "не могу представить зачем бы могло понадобиться подобное объявление", то как раз и имел в виду, что разбираться с подобной программой будет весьма затруднтельно. Опять же, если вы объявляете переменную типа
Matrix4: TMatrix4;
то она уже является указателем.
Если объявляете переменную
M4: PMatrix4;
то она будет фактически указателем на указатель.
Предположим, что в классе есть поле
Name: string;
Сможете без ошибки написать обращение к этому полю через M4?
MylnikovDm
постоялец
 
Сообщения: 103
Зарегистрирован: 15.02.2007 21:26:10
Откуда: Челябинск

Сообщение trifon » 18.02.2007 14:37:17

В паскале я не силён, поэтому в данный момент сказать на эту тему ничего немогу.
В С++ например если есть указатель "class *M4;" обращение к его членам проще проще некуда "M4->Name".
Если в паскале этого сделать нельзя - это проблема убогого синтаксиса.
Зачем вообще тогда в паскале нужны указатели?
И как такое возможно для одних типов указатели можно использовать, а для других нет?
trifon
постоялец
 
Сообщения: 135
Зарегистрирован: 24.12.2006 12:08:35

Сообщение Cheb » 18.02.2007 19:55:48

[чешет в затылке] Да?.. А я-то всю жизнь думал, в Паскале все классы изначально указатели, почему и никакие дополнительные навороты не нужны.

В паскале я не силён, поэтому в данный момент сказать на эту тему ничего немогу.[...]Если в паскале этого сделать нельзя - это проблема убогого синтаксиса.

Ну, в С++ я не силён, но раз такие вещи надо указывать вручную - это явный признак убогого синтаксиса :wink:

З.Ы. Дельфи и FPC в режиме Дельфи, ЕМНИП, позволяют адресоваться к полям указателя на объект класса как к полям просто объекта. Но сам я подобными извращениями никогда не пользовался, так что не скажу.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

Сообщение Sergei I. Gorelkin » 19.02.2007 02:00:09

В Паскале предприняты определенные меры по очистке языка от спецсимволов. Отсюда и классы, которые являются указателями, и присущее Дельфи авто-разименование указателей. Указатели можно, как и в C++, использовать для всего, но в 99% случаев без них можно обойтись.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 1

Рейтинг@Mail.ru