Перегрузка ToString

Вопросы программирования и использования среды Lazarus.

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

Перегрузка ToString

Сообщение Koder » 24.12.2020 20:31:33

Прошу помощи, нет сил уже, Гугл не помогает

Вот простая консольная программка:

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

type

TMyClass = class
  public
   function ToString: string; override;
end;

function TMyClass.ToString: string;
  begin
   result := 'hello';
  end;

var

mc: TMyClass;

begin

mc := TMyClass.Create;

WriteLn(mc);

ReadLn;

end.


Выходит ошибка "project1.lpr(23,12) Error: Can't read or write variables of this type" на строке с WriteLn(mc);

Что я делаю не так?
Koder
незнакомец
 
Сообщения: 2
Зарегистрирован: 21.12.2020 14:27:41

Re: Перегрузка ToString

Сообщение iskander » 25.12.2020 00:42:11

Код: Выделить всё
  WriteLn(mc.ToString);
?
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Re: Перегрузка ToString

Сообщение Seenkao » 25.12.2020 01:01:09

iskander писал(а):mc.ToString

жестоко... ))) пишут и не знаю сами, что пишут.
Seenkao
энтузиаст
 
Сообщения: 502
Зарегистрирован: 01.04.2020 03:37:12

Re: Перегрузка ToString

Сообщение скалогрыз » 25.12.2020 05:48:01

Seenkao писал(а):жестоко... ))) пишут и не знаю сами, что пишут.

я бы не стал так радикально говорить! судя по-заявлению человек пришёл в Паскаль из С#, где Console.WriteLine, как раз использует ToString().

Желательного функционала можно было БЫ добиться, если Write/WriteLn проверяли бы наличие implicit-cast операторов.

Вот это код не скомпилируется (хотя мог бы!)
Код: Выделить всё
operator := (o: TObject): AnsiString;
begin
  if Assigned(o) then result:= o.tostring()
  else Result := 'nil';
end;   

var
  o : TMyClass;
begin
  o := TMyClass.Create;
  Writeln(o); // ошибка
end.


Зато так тоже можно:
Код: Выделить всё
operator := (o: TObject): AnsiString;
begin
  if Assigned(o) then result:= o.tostring()
  else Result := 'nil';
end;   

var
  o : TMyClass;
  s: string;
begin
  o := TMyClass.Create;
  s := o;
  Writeln(s);
end.

или даже так:
Код: Выделить всё
operator := (o: TObject): AnsiString;
begin
  if Assigned(o) then result:= o.tostring()
  else Result := 'nil';
end;   

var
  o : TMyClass;
begin
  o := TMyClass.Create;
  Writeln(string(o)); // явное приведение из неявного
end.



При ЯВНОМ приведении типа, можно добиться желаемого результата:
Код: Выделить всё
operator explicit (o: TObject): AnsiString;
begin
  if Assigned(o) then result:= o.tostring()
  else Result := 'nil';
end;   

var
  o : TMyClass;
begin
  o := TMyClass.Create;
  Writeln(String(o));
end.

Но тогда уж, проще писать сразу o.ToString();

может и поправят когда-нить!
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Перегрузка ToString

Сообщение runewalsh » 25.12.2020 17:10:12

Поаккуратнее с неявными кастами, я себе однажды попробовал добавить касты между всеми типами векторов, чтобы можно было смешивать их типы в выражениях:
Код: Выделить всё
   operator +(const a, b: Vec3f32): Vec3f32;
   operator :=(const a: Vec3i16): Vec3f32;
   operator :=(const a: Vec3u8): Vec3f32;

var
   x: Vec3f32;
   d: Vec3i16;
   u: Vec3u8;
begin
   x := x + d + u;
end;

и вместо трёх секунд всё стало компилироваться по ПОЛМИНУТЫ, пришлось вернуть всё назад и больше не вспоминать. При этом код, явно приводящий векторы через перегруженную Make:
Код: Выделить всё
   operator +(const a, b: Vec3f32): Vec3f32;
   class function Vec3f32.Make(const a: Vec3i16): Vec3f32;
   class function Vec3f32.Make(const a: Vec3u8): Vec3f32;

var
   x: Vec3f32;
   d: Vec3i32;
   u: Vec3u8;
begin
   x := x + Vec3f32.Make(d) + Vec3f32.Make(u);
end;

— компилируется с прежней скоростью.
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 578
Зарегистрирован: 27.04.2010 00:15:25

Re: Перегрузка ToString

Сообщение haword » 26.12.2020 17:33:03

Koder писал(а):Выходит ошибка "project1.lpr(23,12) Error: Can't read or write variables of this type" на строке с WriteLn(mc);

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

по-русски же пишет - неможу считать или записать переменную этого типа. поэтому надо глянуть что WriteLn принимает как аргумент, и увидим что классы он не принимает
The Write command accepts an arbitrary number of arguments. The V1, V2, V3 in the declaration here are in fact just samples, the actual number may be much higher. The types of arguments (Type1 etc.) are limited to the following types:
Any character type.
Any string type (including pchar).
Any ordinal type (integer, enumerated).
The Int64 and QWord type.
Any floating-point type (such as double, single, extended).

мораль сей басни такова - учитесь читать что вам пишет компилятор или не занимайтесь программированием )
haword
постоялец
 
Сообщения: 301
Зарегистрирован: 02.03.2006 11:34:40

Re: Перегрузка ToString

Сообщение Vadim » 27.12.2020 05:14:56

haword писал(а):мораль сей басни такова - учитесь читать что вам пишет компилятор или не занимайтесь программированием )

Злая школьная учителка заставляет. Причём - удалёнская, от этого ещё страшнее... :D
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск


Вернуться в Lazarus

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 34

Рейтинг@Mail.ru