Страница 1 из 1

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

СообщениеДобавлено: 05.01.2014 15:21:39
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;


Что я делаю не так?

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

СообщениеДобавлено: 06.01.2014 12:39:49
MiniQ
AlexP писал(а):operator +(c1,c2:tmyobject)r:tmyobject;begin r.i:=c1.i+c2.i;end;

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

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


а вот тут конструктор лишний, объект будет перезаписан возвращенным значением

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

СообщениеДобавлено: 06.01.2014 13:09:44
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, т.е. явно бессмысленный.

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

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

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

СообщениеДобавлено: 10.01.2014 22:20:02
Дож
Код: Выделить всё
тогда ошибки нет, но результат сложения равен 70248296, т.е. явно бессмысленный.

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

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

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