Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.09.2015, 15:28   #11
Rhasta-Rhasta
Пользователь
 
Регистрация: 13.09.2015
Сообщений: 16
По умолчанию

JUDAS, к сожалению, недостаточная степень просветления в вопросах программирования не позволяет мне оценить весь масштаб обвалившегося на меня счастья, которое должно было последовать за вашим последним замечанием...
В приведённых процедурах/функциях вроде как разобрался, единственное, не совсем понимаю как весь этот аппарат прикрутить к record'у дабы организовать перегрузку, или это тоже делается в обход?

Последний раз редактировалось Rhasta-Rhasta; 20.09.2015 в 15:35.
Rhasta-Rhasta вне форума Ответить с цитированием
Старый 20.09.2015, 18:56   #12
саша40
Участник клуба
 
Регистрация: 12.09.2012
Сообщений: 1,030
По умолчанию

Цитата:
Сообщение от Rhasta-Rhasta Посмотреть сообщение
В приведённых процедурах/функциях вроде как разобрался, единственное, не совсем понимаю как весь этот аппарат прикрутить к record'у дабы организовать перегрузку, или это тоже делается в обход?
просто замени record на class и добавь constructor и destructor.
Что нужно программисту: Компьютер, Среда программирование, Воображение, Прямые руки, Мозги, Знания этой среды программирования.
Программист-это профессия, а программирование-это моё хобби.
саша40 вне форума Ответить с цитированием
Старый 20.09.2015, 21:05   #13
Rhasta-Rhasta
Пользователь
 
Регистрация: 13.09.2015
Сообщений: 16
По умолчанию

Разобрался с основой, буду адаптировать под свои нужды. Большое спасибо!
Rhasta-Rhasta вне форума Ответить с цитированием
Старый 21.09.2015, 16:46   #14
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

Э, кхм, нашли кого слушать.

Перегрузка операторов действительно доступна только для рекордов, но там где она доступна, доступны и методы рекордов, что для данной задачи практически покрывает потребности в работе с такими типами, ведь не требуется наследование и полиморфизм, хотя инкапсуляция с сокрытием доступа была бы кстати (это 3 кита ООП и реализации классов). Собственно, перегрузки базовых операторов должно быть достаточно - арифметических, сравнения, присвоения (с неявным и с явным приведением).
Что до перегрузки, как Вы выражаетесь, базовых операций RTL типа SetLength, то тут достаточно инкапсуляции - например, в конструкторе задать размерность массива или иные необходимые действия, или в методе в каком, особый синтаксис (конструктор без параметров) позволяет инициализировать запись по умолчанию как хотите, для этого ничего делать не надо, всё работает просто при объявлении переменной. Также доступны итераторы - возможность описания поведения типа при использовании его с инструкцией for x in y - в стандартной справке, и в дельфи-блогах етсь обзорная информация, остальное пробуйте, так лучше закрепится
Насчёт 4 пункта - читайте про дженерики www.keeper89.blogspot.com/2011/07/delphi.html

Последний раз редактировалось phomm; 21.09.2015 в 16:48.
phomm вне форума Ответить с цитированием
Старый 21.09.2015, 20:11   #15
Rhasta-Rhasta
Пользователь
 
Регистрация: 13.09.2015
Сообщений: 16
По умолчанию

phomm, мир никогда не будет таким, как прежде. Буду пробовать.
Статья про дженерики великолепна.
Rhasta-Rhasta вне форума Ответить с цитированием
Старый 23.09.2015, 17:20   #16
Rhasta-Rhasta
Пользователь
 
Регистрация: 13.09.2015
Сообщений: 16
По умолчанию

Подскажите, пожалуйста, почему возникает ошибка
Код:
unit MatrixAlg;

interface

type
TVector = record
  V: array of extended;
 private
  function getValue(i: integer): extended;
  procedure setValue(i: integer; Value: extended);
 public
  property p1[i: integer]: extended read getValue write setValue; default;
end;

TMatrix = record
  M: array of TVector;
 private
  function getValue(i,j: integer): extended;
  function getVector(i: integer): TVector;
  procedure setValue(i,j: integer; Value: extended);
  procedure setVector(i: integer; Vector: TVector);
 public
  property p1[i: integer]: TVector read getVector write setVector; default;
  property p1[i,j: integer]: extended read getValue write setValue; default;
end;

procedure setSize(var Vector: TVector; i: integer); overload;
procedure setSize(var Matrix: TMatrix; i: integer); overload;
procedure setSize(var Matrix: TMatrix; i,j: integer); overload;
function Size(Vector: TVector): integer; overload;
function Size(Matrix: TMatrix): integer; overload;
function Last(Vector: TVector): integer; overload;
function Last(Matrix: TMatrix): integer; overload;

implementation

procedure setSize(var Vector: TVector; i: integer);
begin
  setlength(Vector.V,i);
end;

procedure setSize(var Matrix: TMatrix; i: integer);
begin
  setlength(Matrix.M,i);
end;

procedure setSize(var Matrix: TMatrix; i,j: integer);
var k: integer;
begin
  setSize(Matrix,i);
  for k:=0 to i-1 do
  setSize(Matrix[k],j); // There is no overloaded version of 'setSize' that can be called with these arguments (E2250)
end;

function Size(Vector: TVector): integer;
begin
  result:=length(Vector.V);
end;

function Size(Matrix: TMatrix): integer;
begin
  result:=length(Matrix.M);
end;

function Last(Vector: TVector): integer;
begin
  result:=Size(Vector)-1;
end;

function Last(Matrix: TMatrix): integer;
begin
  result:=Size(Matrix)-1;
end;

function TVector.getValue(i: integer): extended;
begin
  result:=V[i];
end;

procedure TVector.setValue(i: integer; Value: extended);
begin
  V[i]:=Value;
end;

function TMatrix.getValue(i,j: integer): extended;
begin
  result:=M[i].V[j];
end;

function TMatrix.getVector(i: integer): TVector;
begin
  result:=M[i];
end;

procedure TMatrix.setValue(i,j: integer; Value: extended);
begin
  M[i].V[j]:=Value;
end;

procedure TMatrix.setVector(i: integer; Vector: TVector);
begin
	M[i]:=Vector;
end;

end.
Rhasta-Rhasta вне форума Ответить с цитированием
Старый 23.09.2015, 17:37   #17
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Текст ошибки угадывать?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 23.09.2015, 20:05   #18
Rhasta-Rhasta
Пользователь
 
Регистрация: 13.09.2015
Сообщений: 16
По умолчанию

Написано же в комментарии. Надо было мне поярче выделить ...
setSize(Matrix[k],j); // There is no overloaded version of 'setSize' that can be called with these arguments (E2250)
ошибка при трансляции

Последний раз редактировалось Rhasta-Rhasta; 23.09.2015 в 20:09.
Rhasta-Rhasta вне форума Ответить с цитированием
Старый 25.09.2015, 09:13   #19
Rhasta-Rhasta
Пользователь
 
Регистрация: 13.09.2015
Сообщений: 16
По умолчанию

Если я правильно понял, свойство Matrix[k] в данном случае подразумевает лишь чтение вектора, а процедура SetSize предполагает его изменение, и это противоречие приводит к такой ошибке. Верно же? Возможно ли это как-то обойти так, чтобы список параметров и способ их записи для процедуры setSize был идентичен процедуре system.setlength?

Последний раз редактировалось Rhasta-Rhasta; 25.09.2015 в 10:23.
Rhasta-Rhasta вне форума Ответить с цитированием
Старый 30.09.2015, 06:56   #20
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

Проперти "массивового" действия (или называют ещё индексаторы) действуют с ограничениями - они являются скорее неявными обращениями к соответствующим аксессорам, нежели обращение к соответствующим данным в требующемся Вам виде.
Поэтому недоступна семантика таких вызовов как у Вас, равно как и для всех пропертей недоступна семантика передачи как var-параметра, и всех подобных операций (детали: Properties, абзац перед разделом Property Access)
Для Вашей задачи можно (и даже нужно, из соображения композиции данных и кода в типе и формальной инкапсуляции типа) написать заменяющий метод прямо внутри типа, а не использовать внешнюю по отношению к типу подпрограмму, которая семантически к типу отношения не имеет (тип - матрица, а Вы её "внутренности" отдаёте коду, работающему с векторами, разделяете логику в разные стороны). Попутно и все остальные подпрограммы раздать типам, имхо, но не обязательно, конечно, достаточно только метод изменения размера одного из векторов матрице отдать типу матрицы, дабы работало.

Если же учитывать, что Вы хотите использовать смесь отдельных процедур и типов (с собственной логикой, такой как операторы, и возможно, методы) и доступ к внутренностям разрешаете при этом - то можно, конечно, написать как угодно. Например, строка, что Вызвала у Вас ошибку переписывается в SetLength(Matrix.M[i].V, j);

Кстати, для таких задач как Ваша, придуманы стандартные обобщённые коллекции Array<> и List<> (модуль Generic.Collections), можно использовать их (и типопараметризовать вектором), почти весь Ваш код их повторяет в велосипедном ключе (излишен, ненадёжен и неполон).

Последний раз редактировалось phomm; 30.09.2015 в 07:05.
phomm вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с матрицами (Delphi) Elenachu Помощь студентам 0 15.01.2014 00:25
Работа с Матрицами (Delphi 7) Дмитрий5 Помощь студентам 0 22.12.2011 21:36
Работа с матрицами (Delphi) Вета Помощь студентам 0 15.04.2009 15:37
Работа с матрицами (Delphi) roman09 Помощь студентам 6 11.04.2009 11:32
Работа с матрицами (delphi) Майструк Татьяна Помощь студентам 3 07.04.2009 20:33