Перегрузка операторов для обьектов с виртуальными методами

Форум для изучающих FPC и их учителей.

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

Ответить
AlexP
новенький
Сообщения: 20
Зарегистрирован: 11.05.2007 19:04:01

Перегрузка операторов для обьектов с виртуальными методами

Сообщение AlexP »

Здравствуйте.

Когда обьекту с перегрузкой операторов сделал метод виртуальным, то при его вызове возникает Access Violation.

Вот обьект -

Код: Выделить всё

type tmyobject=object
i:integer;
 constructor init;
 function get_string:string; virtual;
end;

operator +(c1,c2:tmyobject)r:tmyobject;

implementation

constructor tmyobject.init;
begin
 i:=0;
end;

function tmyobject.get_string:string;
begin
 result:=inttostr(i);
end;

operator +(c1,c2:tmyobject)r:tmyobject;
begin
 r.i:=c1.i+c2.i;
end;



А вот здесь при вызове метода возникает ошибка -

Код: Выделить всё

procedure TForm1.Button1Click(Sender: TObject);
var x:tmyobject;
begin
 x.init;
 x:=x+x;
 form1.Caption:=x.get_string;
end;


Что я делаю не так?
MiniQ
новенький
Сообщения: 81
Зарегистрирован: 28.01.2013 16:31:55

Сообщение MiniQ »

AlexP писал(а):operator +(c1,c2:tmyobject)r:tmyobject;begin r.i:=c1.i+c2.i;end;

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

AlexP писал(а):x.init;
x:=x+x;


а вот тут конструктор лишний, объект будет перезаписан возвращенным значением
AlexP
новенький
Сообщения: 20
Зарегистрирован: 11.05.2007 19:04:01

Сообщение AlexP »

Сейчас попробовал, как вы говорите, убрать лишний конструктор из процедуры

Код: Выделить всё

procedure TForm1.Button1Click(Sender: TObject);
var x:tmyobject;
begin
 //x.init;
 x:=x+x;
 form1.Caption:=x.get_string;
end;


а в оператор добавить конструктор -

Код: Выделить всё

operator +(c1,c2:tmyobject)r:tmyobject;
begin
 r.init;
 r.i:=c1.i+c2.i;
end;


- тогда ошибки нет, но результат сложения равен 70248296, т.е. явно бессмысленный.

А если в процедуре оставить конструктор, то все ОК, и ошибки нет и результат верен.

Только у меня остается вопрос - это правильно, для одного и того же результата вот так использовать два конструктора? Это не приведет к утечке памяти, например, и, может, мне просто сейчас повезло в примере, что и ошибки нет и результат правильный?
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

Код: Выделить всё

тогда ошибки нет, но результат сложения равен 70248296, т.е. явно бессмысленный. 

Инициализацию x всё-таки убирать не нужно было. Нужно и инициализировать и x, и результат сложения.

Код: Выделить всё

Только у меня остается вопрос - это правильно, для одного и того же результата вот так использовать два конструктора? Это не приведет к утечке памяти, например, и, может, мне просто сейчас повезло в примере, что и ошибки нет и результат правильный?

Нет, утечек памяти не произойдёт, потому что при вызове конструктора у object'а неявных выделений памяти не происходит. (Неявные выделения памяти всё-таки могут происходить, если внутри объекта есть поля типа строка или динамический массив, но в этом случае компилятор сам позаботится об их освобождении.)
Ответить