Перегрузка ToString

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

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

Ответить
Koder
незнакомец
Сообщения: 2
Зарегистрирован: 21.12.2020 13:27:41

Перегрузка ToString

Сообщение Koder »

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

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

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

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);

Что я делаю не так?
iskander
энтузиаст
Сообщения: 630
Зарегистрирован: 08.01.2012 18:43:34

Сообщение iskander »

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

  WriteLn(mc.ToString);
?
Seenkao
энтузиаст
Сообщения: 578
Зарегистрирован: 01.04.2020 02:37:12
Контактная информация:

Сообщение Seenkao »

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

жестоко... ))) пишут и не знаю сами, что пишут.
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

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();

может и поправят когда-нить!
Аватара пользователя
runewalsh
энтузиаст
Сообщения: 579
Зарегистрирован: 27.04.2010 00:15:25

Сообщение runewalsh »

Поаккуратнее с неявными кастами, я себе однажды попробовал добавить касты между всеми типами векторов, чтобы можно было смешивать их типы в выражениях:

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

   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;

— компилируется с прежней скоростью.
haword
постоялец
Сообщения: 301
Зарегистрирован: 02.03.2006 10:34:40

Сообщение haword »

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).

мораль сей басни такова - учитесь читать что вам пишет компилятор или не занимайтесь программированием )
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

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

Злая школьная учителка заставляет. Причём - удалёнская, от этого ещё страшнее... :D
Ответить