Текущий архив: 2009.05.10;
Скачать: CL | DM;
Вниз
Можно ли сделать чтоб класс менял размер массива не зная его типа Найти похожие ветки
← →
TInt (2009-03-01 23:18) [0]? То есть тип массива задаёт пользователь этого класса. Даёт ссылку на массив классу, а класс по необходимости корректирует размер массива. Можно так сделать?
← →
Anatoly Podgoretsky © (2009-03-01 23:43) [1]> TInt (01.03.2009 23:18:00) [0]
Нельзя поскольку тип всегда известен. И Дельфи не интерпритатор.
← →
palva © (2009-03-01 23:46) [2]Не бывает массивов, тип элементов которых не известен. А если класс будет всегда предполагать, что массив является массивом указателей или объектов? Это вас не устроит? Только тогда нужно продумать вопрос, кто должен создавать и уничтожать объекты, если фактически вы передадите классу массив объектов.
← →
Palladin © (2009-03-01 23:52) [3]ну почему не бывает... массив вариантов, а замест объктов - интерфейсы... только о производительност конечно придется забыть :)
← →
TInt (2009-03-02 00:28) [4]
> palva © (01.03.09 23:46) [2]
>
> Не бывает массивов, тип элементов которых не известен. А
> если класс будет всегда предполагать, что массив является
> массивом указателей или объектов?
Нет. Массив только рекордов.
> Palladin © (01.03.09 23:52) [3]
>
> ну почему не бывает... массив вариантов, а замест объктов
> - интерфейсы... только о производительност конечно придется
> забыть :)
А как это сделать? В интерфейсах я слаб. Можно какой-нибудь пример?
Производительность в данной задаче почти не важна.
← →
Anatoly Podgoretsky © (2009-03-02 00:29) [5]> Palladin (01.03.2009 23:52:03) [3]
Тип массива вариант, более чем конкретно.
← →
Германн © (2009-03-02 02:00) [6]
> Можно ли сделать чтоб класс менял размер массива не зная
> его типа
>
> TInt (01.03.09 23:18)
Описал бы свою задачу/B>, может и пользы было бы больше.
← →
test © (2009-03-02 05:50) [7]Смотри дженерики в Delphi 2009 List<Intgeger>.
← →
test © (2009-03-02 07:04) [8]Может тебе Variant использовать? Variant может хранить разнородные данные.
← →
test © (2009-03-02 08:12) [9]Только лучше заняться перепроектированием приклада, в том виде в котором ты сейчас это описал это какая то сплошная ошибка получиться.
← →
TUser © (2009-03-02 08:43) [10]TList + ссылки и приведение типов
Или так: все возможные типы - наследники базового класса, который объявлен, как тип элементов массива
← →
Дуб © (2009-03-02 08:49) [11]Написать свой класс масСив. GetMem и дальше с маршем.
← →
Skyle © (2009-03-02 09:02) [12]А может всё-таки использовать интерфейс?
Типа такогоtype
ISizeableArray = interface
procedure SetLength(ANewLength : Integer);
end;
А потом уже этот класс будет получать не сам массив, а его интерфейс?
Хотя не очень понятно, зачем этому классу увеличивать массив с элементами неизвестного типа данных? Что он с новыми элементами делать будет...
← →
Anatoly Podgoretsky © (2009-03-02 09:39) [13]> Skyle (02.03.2009 9:02:12) [12]
Это не страшно, могут и полежать, а вот как увеличить массив, если тип неизвестен, неизвестно сколько памяти надо выделить.
И все равно Дельфи не интерпритатор, что бы подобное делать.
← →
Skyle © (2009-03-02 10:15) [14]
> Anatoly Podgoretsky © (02.03.09 09:39) [13]
Я имел ввиду комбинацию [11] и [12]. То есть эти "массивы записей" обёрнуты в классы, которые реализуют интерфейс, позволяющий снаружи менять размер. Сама работа по изменению делается в самом "классе массива" в реализации интерфейсных методов. Уж сам "класс массива" должен знать, что в нём.
← →
Sapersky (2009-03-02 16:32) [15]Это не страшно, могут и полежать, а вот как увеличить массив, если тип неизвестен, неизвестно сколько памяти надо выделить.
Ну есть разные "додженериковые" способы - просто размер записи или TypeInfo.
Использование дженериков, наверное, самый правильный метод. Плюс к тому, если выбирать из разных BDS - у 2009-го сама IDE стала заметно шустрее. Но здесь неоднократно жаловались на глючность компилятора (сам ещё не успел походить по граблям).
← →
MsGuns © (2009-03-03 12:01) [16]Заменить рекорды объектами, а массив - списком - и пребудет щастье :)
← →
TInt (2009-03-05 05:33) [17]В общем сделал классу событие:
type
TOnGetSetArrayLength = function(isSetArraySize : Boolean;
aNewLen : Integer = 0) : Integer of object;
Пусть пользователь его обрабатывает вот такой простой функцией:function OnGetSetArrayLength(isSetArraySize : Boolean;
aNewLen : Integer = 0) : Integer;
begin
if isSetArraySize then SetLength(Array1, aNewLen)
else Result := Length(Array1);
end;
Конечно, это через ж.., ненужно загромождает код и вообще не удобно. Но а что делать то? Как-то Дельфи абстракций не хватает.
> test © (02.03.09 05:50) [7]
>
> Смотри дженерики в Delphi 2009 List<Intgeger>.
До 2009 ещё не добрался.
> test © (02.03.09 07:04) [8]
>
> Может тебе Variant использовать?
А как именно то?
> Дуб © (02.03.09 08:49) [11]
>
> Написать свой класс масСив.
Как понять класс массив?
> Skyle © (02.03.09 09:02) [12]
>
> А может всё-таки использовать интерфейс?
> Типа такого
>
> type
> ISizeableArray = interface
> procedure SetLength(ANewLength : Integer);
> end;
>
> А потом уже этот класс будет получать не сам массив, а его
> интерфейс?
А как это использовать? Где можно посмотреть примеры использования интерфейсов? В исходниках Дельфи как-то совсем не понятно чего они делают.
← →
test © (2009-03-05 05:40) [18]TInt (05.03.09 05:33) [17]
Variant может хранить данные многих простых и часть сложных типов.
var
av: array[0..2] of Variant;
begin
av[0] := 1;
av[1] := "stroka";
av[2] := now;
end;
Только пользоваться таким тяжело и возможны ошибки.
← →
Skyle © (2009-03-05 07:39) [19]
> TInt (05.03.09 05:33) [17]
> А как это использовать?
Если я правильно понял, то предполагаю что-то типа такого.
Это - твой код.
type
//Этот интерфейс пользователи класса должны реализовывать. Тут только общие методы, необходимые твоему классу для общения с массивами.
ISizeableArray = interface
procedure SetArrayLength(ANewLength : Integer);
end;
TMyWorkerClass = class ......
private
FArray : ISizeableArray;
public
procedire SetArray(AArray : ISizeableArray);
end;
................
implementation
.......
procedure TMyWorkerClass.SetArray(AArray : ISizeableArray);
begin
FArray := AArray;
end;
Потом где-то, где нужно увеличивать этот массив, будет такой код
.........
FArray.SetArrayLength(MyNewLength);
.....
При этом пользователи класса пишут свои собственные классы для массивов, при этом они обязаны реализовать этот интерфейс в своём классе. Самый простой пример использования наверное вот такой.
(это уже пишет пользователь)
type
TUserArray = class(TList, ISizeableArray)
protected
.....
procedure SetArrayLength(ANewLength : Integer);
.....
end.
......
implementation
......
procedure TUserArray.SetArrayLength(ANewLength : Integer);
begin
Count := ANewLength;
end;
Тебе это передаётся в класс примерно так...
var
Worker : TMyWorkerClass;
begin
....
Worker.SetArray(Self);
......
end;
То же самое можно сделать и с использованием базового класса для массива, вместо интерфейса. Основное отличие - интерфейс можно реализовать в любом классе,
имеющемся у пользователя. А в случае с базовым классом от него придётся наследоваться.
Как-то так....
← →
Sapersky (2009-03-05 10:48) [20]Конечно, это через ж.., ненужно загромождает код и вообще не удобно. Но а что делать то? Как-то Дельфи абстракций не хватает.
см. DynArraySetLength. В качестве примера можно использовать это:
http://sapersky.narod.ru/files/Arrays.rar
Класс у меня тоже есть, кстати. Но рекомендовать его как образец для подражания я бы не рискнул, код "грязноват", много барахла поднакопилось.
Страницы: 1 вся ветка
Текущий архив: 2009.05.10;
Скачать: CL | DM;
Память: 0.52 MB
Время: 0.007 c