Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Приведение типов, поясните или дайте ссылку на доку, плиз 
V
    Опции темы
Kbl4AH
Дата 20.1.2009, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 741
Регистрация: 1.4.2008
Где: Вятка

Репутация: 4
Всего: 15



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

procedure TForm1.Button1Click(Sender: TObject);
var
  S: string;
  I: Integer;
  O1, O2: TObject;
begin
  S := '123';
  I := 55;
  O1 := TObject(S);
  O2 := TObject(I);
  ShowMessage(string(O1));            // 1
  ShowMessage(string(O2));            // 2
  ShowMessage(string(Integer(O2)));   // 3
  ShowMessage(IntToStr(Integer(O2))); // 4
end;

Почему 2-я строка не работает, хотя 1-я - работает?
Почему 3-я строка не работает, хотя 4-я - работает?
 smile 
И почему 
Код

IntToStr(Integer(O1)) <> IntToStr(S)
?

Это сообщение отредактировал(а) Kbl4AH - 20.1.2009, 14:53
PM MAIL ICQ   Вверх
Alexeis
Дата 20.1.2009, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Есть 2 понятия приведение типов и преобразование типов.

1) Например если юникодной строке присвоить анси строку, то выполниться преобразование типов. Создастся новая строка и символы будут преобразованы. Преобразование типов возможно только если есть функция преобразования (встроенная или нет).

2) Есть приведение типов. Приведение лишь говорит компилятору, что указанную область памяти нужно считать указанного типа. Например указатель можно преобразовать к LongInt, поскольку они одного размера. Но даже не смотря на это компилятор может накладывать ограничения на преобразования типов по смысловым соображениям. Делается это для того чтобы избежать ошибки при написании кода.

  Преобразование типов не следует использовать, кроме как в простейших случаях.

Добавлено через 4 минуты и 18 секунд
ShowMessage(string(O1)); - привет к краху программы, потому что типы несовместимы.

Добавлено через 8 минут и 24 секунды
  Хотя если быть точным O1 := TObject(S); уже ошибка. Когда умрет программа это уже вопрос вероятности.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alexeis
Дата 20.1.2009, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Рассмотрим код
Код

procedure TForm1.FormCreate(Sender: TObject);
var
  S1 : AnsiString;
  S2 : WideString;

  p  : Pointer;
  c  : LongInt;
begin
  SetLength(S1, 20);
  S1[5] := 'g';
  S2 := WideString(S1);

  GetMem(p, 20);
  c := LongInt(p);

end;


и то что происходит на самом деле
1) я часть присвоение строк.
Код

Unit1.pas.35: S2 := WideString(S1);
00454217 8D45F4           lea eax,[ebp-$0c]
0045421A 8B55F8           mov edx,[ebp-$08]
0045421D E8160FFBFF       call @WStrFromLStr

Команды lea eax,[ebp-$0c] и  mov edx,[ebp-$08] передают аргументы в функцию WStrFromLStr, после чего происходит ее вызов 
call @WStrFromLStr
В данном случае функция преобразования строк WStrFromLStr системная

Второй пример
Код

Unit1.pas.38: c := LongInt(p);
0045422F 8B45F0           mov eax,[ebp-$10]
00454232 8945EC           mov [ebp-$14],eax


Загрузили значение адреса указателя в регистр eax mov eax,[ebp-$10], затем mov [ebp-$14],eax, записали эту величину в переменную типа LongInt. 
  Это пример преобразования приведения типов одного размера. 

Внешне оба примера неотличимы, но чтобы знать что реально происходит нужно владеть языком.
Во всех ваших примерах нет ни одного правильного преобразования, поскольку их просто не существует.

В С++ преобразование типа также неотличимо от вызова конструктора. В Delphi начиная с версии 2007 также введена система преобразования типов для классов и записей. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Kbl4AH
Дата 20.1.2009, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 741
Регистрация: 1.4.2008
Где: Вятка

Репутация: 4
Всего: 15



Мдя smile 
Хорошо, тогда по-другому...
Мне нужна весчь типа TObject, которая могла бы хранить набор символов или число... И чтобы каким-то образом из этой весчи хранимую информацию можно было получить...
Как этого достичь?

Это сообщение отредактировал(а) Kbl4AH - 20.1.2009, 15:54
PM MAIL ICQ   Вверх
MetalFan
Дата 20.1.2009, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 22
Всего: 128



Цитата(Kbl4AH @  20.1.2009,  15:51 Найти цитируемый пост)
Как этого достичь?

написать класс, который будет в себе хранить "набор символов или число"


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Kbl4AH
Дата 20.1.2009, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 741
Регистрация: 1.4.2008
Где: Вятка

Репутация: 4
Всего: 15



Цитата(MetalFan @  20.1.2009,  16:02 Найти цитируемый пост)
написать класс, который будет в себе хранить "набор символов или число"

А можно smile ?
PM MAIL ICQ   Вверх
MetalFan
Дата 20.1.2009, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 22
Всего: 128



object pascal совсем не изучали?
да хоть както так:
Код

TDataObject = class( TObject )
private
  FString: string;
  FInt: integer;
public 
  property StringData: string read FString write FString;
  property IntegerData: integer read FInt write FInt;
end;




--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Kbl4AH
Дата 20.1.2009, 16:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 741
Регистрация: 1.4.2008
Где: Вятка

Репутация: 4
Всего: 15



Цитата(MetalFan @  20.1.2009,  16:33 Найти цитируемый пост)
object pascal совсем не изучали?

Вы заставляете меня краснеть smile 
PM MAIL ICQ   Вверх
Kbl4AH
Дата 20.1.2009, 20:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 741
Регистрация: 1.4.2008
Где: Вятка

Репутация: 4
Всего: 15



Что-то у меня ничего не работает((( В чем же дело?
Код

  TAObject = class(TObject)
  private
    FValue: string;
  public
    property Value: string read FValue write FValue;
  end;

var
  Form1: TForm1;
  AObject: TAObject;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
begin
  AObject := TAObject.Create;
  for I := 0 to Memo1.Lines.Count - 1 do
    begin
      AObject.Value := IntToStr(I);
      Memo1.Lines.Objects[I] := AObject;
    end;
  for I := 0 to Memo1.Lines.Count - 1 do
    Caption := Caption + ' ' + (Memo1.Lines.Objects[I] as TAObject).Value;
end;

end.

PM MAIL ICQ   Вверх
bems
Дата 21.1.2009, 19:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 18
Всего: 88



ты создал только один объект. В результате (Memo1.Lines.Objects[I] as TAObject).Value это одно и то же для любого I
Или передвинь создание объекта внутрь цикла, или и правда тут можно обойтись простым приведением:
Код

Memo1.Lines.Objects[I] := TObject(I)



--------------------
Обижено школьников: 8
PM MAIL   Вверх
Kbl4AH
Дата 21.1.2009, 23:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 741
Регистрация: 1.4.2008
Где: Вятка

Репутация: 4
Всего: 15



Дело не в этом... я даже одно и тоже значение не могу прочесть(((
PM MAIL ICQ   Вверх
THandle
  Дата 22.1.2009, 00:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хранитель Клуба
Group Icon
Награды: 1



Профиль
Группа: Админ
Сообщений: 3639
Регистрация: 31.7.2007
Где: Moscow, Dubai

Репутация: 50
Всего: 372



Kbl4AH, Momo не поддерживает объекты. Посмотри тему:

http://www.delphikingdom.com/asp/answer.asp?IDAnswer=66586

В докозательство от меня попробуй вот эти два кода(в первом случае ListBox, во втором Memo):


Сам класс:
Код


  TAObject = class(TObject)
  private
    FValue: string;
  public
    constructor Create(const AValue: String);
    property Value: string read FValue write FValue;
  end;

...

constructor TAObject.Create(const AValue: String);
begin
  FValue := AValue;
end;


ListBox:

Код


procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to ListBox1.Items.Count - 1 do
      ListBox1.Items.Objects[I] := TAObject.Create(IntToStr(I));
  for I := 0 to ListBox1.Items.Count - 1 do
    Caption := Caption + ' ' + (ListBox1.Items.Objects[I] as TAObject).Value;
end;





Memo:

Код

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to Memo1.Lines.Count - 1 do
      Memo1.Lines.Objects[I] := TAObject.Create(IntToStr(I));
  for I := 0 to Memo1.Lines.Count - 1 do
    Caption := Caption + ' ' + (Memo1.Lines.Objects[I] as TAObject).Value;
end;



Memo и ListBox Должны быть заполнены естественно smile
PM   Вверх
Kbl4AH
Дата 22.1.2009, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 741
Регистрация: 1.4.2008
Где: Вятка

Репутация: 4
Всего: 15



Ответы в ссылке прочитал...
Так не честно smile Я ж про мему такое не знал...
Зато теперь узнал smile 
Действительно, пример с мемо выдает ошибку, а с листбоксом работает как надо.
И все-таки, в данном случае можно использовать приведение типов или лучше этого не делать и использовать класс?

THandle, Alexeis, MetalFan, bems, спасибо!
PM MAIL ICQ   Вверх
Alexeis
Дата 22.1.2009, 10:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Цитата(Kbl4AH @  22.1.2009,  09:06 Найти цитируемый пост)
Я ж про мему такое не знал...

  Это не мема виновата, это тянется от предка TStrings и есть во всех его потомках.

Если что операция (Memo1.Lines.Objects[I] as TAObject).Value довольно медленная, но безопасная, в плане того что ничего ни где не затрешь.
оператор as при каждом обращении будет производить проверку RTTI с тем чтобы удостовериться действительно указанный объект имеет тип TAObject, если нет, то он будет проверять всех его предков, если не найдет ни одного соответствующего предка то вернет nil и гарантированно произойдет при первом же обращении AV.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
THandle
Дата 22.1.2009, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хранитель Клуба
Group Icon
Награды: 1



Профиль
Группа: Админ
Сообщений: 3639
Регистрация: 31.7.2007
Где: Moscow, Dubai

Репутация: 50
Всего: 372



Kbl4AH, твой случай(кстати зачем тут два цикла? можно и в один загнать)

Код

TAObject = class(TObject)
  private
    FValue: string;
  public
    constructor Create(const AValue: String);
    property Value: string read FValue write FValue;
  end;

...

constructor TAObject.Create(const AValue: String);
begin
  Inherited Create;
  FValue := AValue;
end;



Код

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to ListBox1.Items.Count - 1 do
    ListBox1.Items.Objects[I] := TAObject.Create(IntToStr(I));
  for I := 0 to ListBox1.Items.Count - 1 do
    Caption := Caption + ' ' + (ListBox1.Items.Objects[I] as TAObject).Value;
end;


Еще посмотри, может будет интересно:

http://delphist.ru/privedenie-tipov/

Добавлено через 53 секунды
Цитата(Alexeis @  22.1.2009,  10:33 Найти цитируемый пост)
nil и гарантированно произойдет при первом же обращении AV. 


Поэтому придумали еще и is smile
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0720 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.