Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.03.13;
Скачать: [xml.tar.bz2];

Вниз

Operator not applicable to this operand type   Найти похожие ветки 

 
XP   (2005-03-01 12:24) [0]

Надоело об стену стучаться головой. Подскажите, пожалуйста.

unit urInterfaces;

interface

type
 IrIniFile = interface
   function GetData: string; stdcall;
 end;

...


//-----------------------------------------

unit urIniFile;

interfaces

uses
 urInterfaces;

type
 TrIniFile = class(TObject, IrIniFile)
 protected
   function GetData: string; stdcall;
 end;

implementation

uses
 urCore;

...


//-----------------------------------

unit urCore;

interface
 
uses
 urInterfaces, urIniFile;

type  
 TrCore = class
 private
   m_IniFile: IrIniFile;
 public
   constructor Create;
 end;

implementation

constructor TrCore.Create;
begin
 m_IniFile := TrIniFile.Create as IrIniFile; // остановка компилятора
end;


На месте остановки пишет: Operator not applicable to this operand type

Вместе с тем, TrIniFile явно объявлен как class(TObject, IrIniFile).

Кроме того, IDE упорно отказывается "ходить" по исходникам по Ctrl + LeftClick.

Все файлы лежат в одной папке. Больше нигде исходников нет - только в этой папке. То-есть, использование разных DCU исключено - специально перепроверил.

Что он хочет-то?... Где это я так сильно споткнулся?...


 
Димон   (2005-03-01 12:26) [1]

гуид проставь

ctrls+shilf+g ^)))


 
XP   (2005-03-01 12:30) [2]

Спасибо, Димон, за подсказку, но он там стоит.
Я в примере не привел, чтобы не засорять текст.


 
Димон   (2005-03-01 12:33) [3]


> Спасибо, Димон, за подсказку, но он там стоит.

слабо верится. Должно работать, если он стоит :)

Ты где его ставишь? Надо же внутри описания интерфейса. А ты где?

И вообще, почему потомок TObject? У тя работать не дожно, т.к. ты не реализовал _AddRef и прочие методы?


 
clickmaker ©   (2005-03-01 12:38) [4]

угу, должно быть TInterfacedObject


 
Димон   (2005-03-01 12:40) [5]

или самому реализовать нужные методы


 
Чапаев ©   (2005-03-01 12:42) [6]

m_IniFile := TrIniFile.Create; -- а так?


 
XP   (2005-03-01 12:45) [7]

Ё... ну, упростил, чтобы проще было понять.
Вот, реальные интерфейсы и классы:

//----------------------------

unit urInterfaces;

interface

type
   IrComponent = interface(IUnknown)
 ["{898ADB4F-A411-4AF3-96E6-F2A4CB21F0E4}"]
   // Возвращает имя компонента в системе
   function Get_ComponentName: string; stdcall;
   // Отображает окно свойств компонента (с использованием службы представления)
   procedure ShowPropertiesDialog; stdcall;
 (* Properties ****)
   property ComponentName: string read Get_ComponentName;
 end;

...

 IrIniFile = interface(IrComponent)
 ["{CA6FAC79-F754-4A03-8D63-00FE2A2A4C83}"]
   // Возвращает полный путь к папке модулей.
   function Get_ModulePath: string; stdcall;
   // Возвращает имя основной базы данных.
   function Get_MainDBName: string; stdcall;
   // Возвращает полный путь к файлу базы данных.
   function Get_MainDBFileName: string; stdcall;
   // Выводит диалог выбора start-файла при запуске системы.
   function DialogConnect: TrResult; stdcall;
 (* Properties ****)
   property ModulePath: string read Get_ModulePath;
   property MainDBName: string read Get_MainDBName;
   property MainDBFileName: string read Get_MainDBName;
 end;


...

 IrCore = interface(IrComponent)
 ["{73DA798B-DADA-43B8-9785-83F6ACD45520}"]
   function Get_IniFile: IrIniFile; stdcall;
 (* Properties ****)
   property IniFile: IrIniFile read Get_IniFile;
 end;

//----------------------------

unit urCommon;

interface

uses
 urInterfaces;

type
 TrComponent = class(TObject, IrComponent)
 private
   m_iRefCount: integer;
 protected
   function _AddRef: integer; stdcall;
   function _Release: integer; stdcall;
   function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;
 protected
   procedure ShowPropertiesDialog; virtual; stdcall; abstract;
   function Get_ComponentName: string; virtual;  stdcall; abstract;
 public
   constructor Create; virtual;
   destructor Destroy; override;
 end;


//----------------------------

unit urIniFile;

interface

uses
 urInterfaces, urCommon;

type
 TrIniFile = class(TrComponent, IrIniFile)
 private
   m_IniFile: TIniFile;
   m_MainDBSection: string;
 protected
   function DialogConnect: TrResult; stdcall;
   function Get_ComponentName: string; override; stdcall;
   function Get_MainDBFileName: string; stdcall;
   function Get_MainDBName: string; stdcall;
   function Get_ModulePath: string; stdcall;
   procedure ShowPropertiesDialog; override; stdcall;
 public
   constructor Create; override;
   destructor Destroy; override;
 end;


// --------------------------------

unit urCore;

interface

uses
 urInterfaces, urCommon, urIniFile...;

type
 TrCore = class(TrComponent, IrCore)
 private
   m_IniFile: IrIniFile;
   ...
 public
   constructor Create; override;
   ...
 end;

implementation

constructor TrCore.Create;
begin
 inherited Create;
 m_IniFile := TrIniFile.Create as IrIniFile; // стоп...
 ...
end;


 
XP   (2005-03-01 12:48) [8]

m_IniFile := TrIniFile.Create; -- а так?

Как ни странно, но это компилятор воспринимает. :)
Спасибо.
Только вот, кто бы еще объяснил, чем его не устраивает конструкция с использованием as?


 
VMcL ©   (2005-03-01 12:48) [9]

>>XP   (01.03.05 12:45) [7]

В данном случае "as" не нужен, AFAIR:
m_IniFile := TrIniFile.Create;


 
Димон   (2005-03-01 12:50) [10]


> Как ни странно, но это компилятор воспринимает. :)

правда странно. Я обычно, правда,не делаю приведение сразу после конструктора. Обычо через вр. перем.

а := TSomeClass.Create;
i := a as ISomeInt;


Тоже было бы интересно послушать мнения окружающий, почему так?


 
Digitman ©   (2005-03-01 12:51) [11]


> XP   (01.03.05 12:45) [7]


классы, реализующие интерфейсы-наследники IUnknown, обязаны реализовывать как минимум 3 обязательных метода интерфейса IUnknown: QueryInterface(), _AddRef() и _Release()

класс TInterfacedObject УЖЕ реализует эти методы, так что любые его наследники уже не обязаны реализовать их самостоятельно


 
Чапаев ©   (2005-03-01 12:52) [12]

as -- оператор приведения классов. А ты пытаешься class as interface.
Интерфейсу можно присваивать интерфейсы и классы, которые реализуют данный интерфейс.


 
Димон   (2005-03-01 12:52) [13]


>  [11] Digitman ©   (01.03.05 12:51)


он же реализацию не привел. Может ему подсчет ссылок не нужен :)


 
XP   (2005-03-01 12:53) [14]

2 VMcL

Не нужен.
Но и не мешает.
Он в коде остался как "наследие" динамически подключаемого объекта. Раньше вместо TrIniFile.Create стояла функция LoadModule, возвращавшая интерфейс IrComponent - поэтому и использовалось явное приведение. И никому "as" не мешало.

Why?


 
Димон   (2005-03-01 12:53) [15]


>  [12] Чапаев ©   (01.03.05 12:52)


> as -- оператор приведения классов

i: IInt1;
i2: IInt2;
i := i2 as IInt1;


тоже работает. Т.е. as это не только для классов :)


 
XP   (2005-03-01 12:56) [16]

>>as -- оператор приведения классов

Ээээ... А тут позвольте не согласиться. См. "Interface querying".

You can use the as operator to perform checked interface typecasts. This is known as interface querying, and it yields an interface-type expression from an object reference or from another interface reference, based on the actual (runtime) type of the object. An interface query has the form

object as interface

where object is an expression of an interface or variant type or denotes an instance of a class that implements an interface, and interface is any interface declared with a GUID.


 
XP   (2005-03-01 12:59) [17]

Так что же компилятору не понравилось в "as"? :)


 
Чапаев ©   (2005-03-01 13:01) [18]

приносю мои искренние пардоны.


 
XP   (2005-03-01 13:09) [19]

2 Чапаев ©   (01.03.05 13:01) [18]

:)

2 All

И все же?...


 
Digitman ©   (2005-03-01 13:18) [20]


> Димон   (01.03.05 12:52) [13]
> он же реализацию не привел. Может ему подсчет ссылок не
> нужен


да мало ли чего ему не нужно !
коль метод декларирован в интерфейсе, и класс реализует этот интерфейс, значит класс ОБЯЗАН реализовать тем или иным образом ВСЕ методы этого интерфейса !
а уж подсчет ссылок он там будет делать или мух считать - это его личное дело)


> XP


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


 
XP   (2005-03-01 13:29) [21]

2 Digitman

См. [7] - объявление классов TrComponent, TrIniFile

А потом и потанцуем... :)


 
Digitman ©   (2005-03-01 13:39) [22]


> XP   (01.03.05 13:29) [21]
> потом и потанцуем


нет, сначала мы потанцуем вокруг
function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;


 
XP   (2005-03-01 13:48) [23]

нет, сначала мы потанцуем вокруг
function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;


К чему это выделение virtual? Чем это может помешать?


 
Набережных С. ©   (2005-03-01 13:57) [24]

У тебя IUnknown классом не реализуется. AS его у объекта запрашивать должен, тот ответит отказом, компилятор это знает.


 
Digitman ©   (2005-03-01 13:59) [25]


> К чему это выделение virtual? Чем это может помешать?


разуваем глаза, читаем справку :

Methods cannot be declared as virtual, dynamic, abstract, or override. Since interfaces do not implement their own methods, these designations have no meaning.

декларация метода класса, реализующего интерфейс, должна в точности соответствовать декларации соотв.метода в декларации интерфейса, реализуемого этим классом


 
Набережных С. ©   (2005-03-01 13:59) [26]

Точнее даже так: IUnknown должен быть добыт из класса на этапе компиляции, а AS выльется запрос QueryInterface.


 
Димон   (2005-03-01 13:59) [27]


>  [24] Набережных С. ©   (01.03.05 13:57)
> У тебя IUnknown классом не реализуется. AS его у объекта
> запрашивать должен, тот ответит отказом, компилятор это
> знает.

разве? разве iinteface не аналог iunknown и просто interface не эквивалент interface(IInteface)?


 
Набережных С. ©   (2005-03-01 14:01) [28]


> Димон   (01.03.05 13:59) [27]

А какая разница, аналог или нет? TObject никакой не реализует.


 
Digitman ©   (2005-03-01 14:02) [29]


> Димон   (01.03.05 13:59) [27]


> просто interface не эквивалент interface(IInteface)?


объявление IMyInterface = interface;
эквивалентно IMyInterface = interface(IUnknown);

подобно тому, что объявление TMyObject = class;
эквивалентно TMyObject = class(TObject);


 
Набережных С. ©   (2005-03-01 14:03) [30]

В общем, надо объявить так
TrIniFile = class(TObject, IUnknown, IrIniFile)


 
Димон   (2005-03-01 14:03) [31]


>  [28] Набережных С. ©   (01.03.05 14:01)

Не-е-е-е, Ты что-то не то говоришь:))) Наверное в приведенном коде не до конца разобрался. :)


>  [29] Digitman ©   (01.03.05 14:02)

Да знаю я :) Это наводящий вопрос бы [27] :)


 
Набережных С. ©   (2005-03-01 14:04) [32]

Или TInterfacedObject и не маяться...ну сами знаете чем:)


 
Димон   (2005-03-01 14:05) [33]


>  [30] Набережных С. ©   (01.03.05 14:03)

А... так более понятно:) Прости, не понял сначала


 
Набережных С. ©   (2005-03-01 14:05) [34]


> Димон   (01.03.05 14:03) [31]

Да ты проверь, дяденька, попробуй, в CPU View загляни, ага. Хуже-то от этого не будет:)


 
Димон   (2005-03-01 14:06) [35]


>  [34] Набережных С. ©   (01.03.05 14:05)

Я ужо извинился. Ты выразился не вполне понятно просто :)))


 
XP   (2005-03-01 14:13) [36]

TrIniFile = class(TObject, IUnknown, IrIniFile)

IrIniFile порожден от IrComponent, который, в свою очередь, порожден от IUnknown. См. [7].
Смысл?

2 Digitman ©   (01.03.05 13:59) [25]

VCL - Classes.pas

TComponent = class(TPersistent, IInterface, IInterfaceComponentReference)
 ...
 { IInterface }
 function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;  
 ...
end;


Что сие может обозначать?...


 
Набережных С. ©   (2005-03-01 14:13) [37]


> Димон   (01.03.05 14:06) [35]

Дык время посмотри:) Когда писал, [33] еще не было. Да вроде и ничего такого не сказал...Но если все-таки обидел - искренние извинения, совершенно не хотел.

> Ты выразился не вполне понятно просто

Да, бывает со мной. Кажется, если мне очевидно, то и другим тоже. Есть такой грех:(


 
Димон   (2005-03-01 14:14) [38]


> 34] Набережных С. ©   (01.03.05 14:05)

да, интересная информация. Никогда об этом не задумывался, т.к. всегда iunknown реализовывал, даже если не пользовался TIntefacedObject.

Благодарю :)


 
vuk ©   (2005-03-01 14:17) [39]

to Digitman:
>декларация метода класса, реализующего интерфейс, должна в
>точности соответствовать декларации соотв.метода в декларации
>интерфейса, реализуемого этим классом
Значит так. Метод не может быть объявлен virtual при объявлении в интерфейсе (если так можно сказать, они там все virtual), но при реализации в классе метод может иметь любые модификаторы, которые не влияют на способ передачи параметров. В приведенном примере virtual написано именно в реализации.


 
Набережных С. ©   (2005-03-01 14:17) [40]


> XP   (01.03.05 14:13) [36]
> IrIniFile порожден от IrComponent, который, в свою очередь,
> порожден от IUnknown

С точки зрения реализации интерфейса объектом, это не имеет никакого значеня. Реализован только тот, который явно объявлен в классе или в его, класса, предках. Все предки интерфейса - побоку.


 
Digitman ©   (2005-03-01 14:18) [41]


> Надоело об стену стучаться головой


конечно же больно)
нет бы - хрясь ! - легким движением руки унаследовать свой класс от TInterfacedobject ... так ведь - нет ! мы легких путей не ищем) ... нам геморрой в причинном месте дороже)


 
Димон   (2005-03-01 14:20) [42]


> [37] Набережных С. ©   (01.03.05 14:13)


Этта что получается, что все as для интерфейсов "ходят" через метод QueryInterface относительно IUnknown?


 
Набережных С. ©   (2005-03-01 14:22) [43]

Просто надо вспомнить, что каждый интерфейс в классе - таблица, и в каждой из них свои AddRef, Release и все остальные унаследованные интерфейсом методы.


 
Набережных С. ©   (2005-03-01 14:22) [44]

Просто надо вспомнить, что каждый интерфейс в классе - таблица, и в каждой из них свои AddRef, Release и все остальные унаследованные интерфейсом методы.


 
Набережных С. ©   (2005-03-01 14:25) [45]


> Димон   (01.03.05 14:20) [42]

Да, если Object as interface. Если interface as interface, то вызывается метод самого исходного интерфейса.


 
Димон   (2005-03-01 14:27) [46]


>  [45] Набережных С. ©   (01.03.05 14:25)

Спасибо. Вообще говоря логично :)))

Полезная информация.

Где тут оценки ставят как на RSDN? :)))



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2005.03.13;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.57 MB
Время: 0.049 c
1-1108454202
BPK
2005-02-15 10:56
2005.03.13
Пошаговая отладка: как не входить в системные unit ы?


1-1109616668
Bloody-Wolf
2005-02-28 21:51
2005.03.13
Функция не работает, что в ней не так?


4-1106922088
juice
2005-01-28 17:21
2005.03.13
Рисую на экране всякие козяблики


8-1101366528
_Nikolay
2004-11-25 10:08
2005.03.13
Как сделать клиентскую область формы на весь экран ?


4-1105224836
Arnold
2005-01-09 01:53
2005.03.13
Проблема с ComboBox на WinApi





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский