Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Интерфейс с перегруженными функциями и его реализация / 21 сообщений из 21, страница 1 из 1
07.12.2017, 11:41:11
    #39565685
Олег Третьяков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
Доброго дня, коллеги.
первый вариант интерфейса
Код: pascal
1.
2.
3.
4.
IConfigController = interface(IInterface)
    procedure Load(const AType: string; ADest: TMemIniFile); stdcall;
    function Save(const AType: string; ASource: TMemIniFile): boolean;  stdcall;
  end;


и объявление в классе
Код: pascal
1.
2.
3.
4.
5.
{IConfigController}
    procedure IConfigController.Load = LoadConfigFile;
    function IConfigController.Save =  SaveConfigFile;
    procedure LoadConfigFile(const AType: string; ADest: TMemIniFile); stdcall;
    function SaveConfigFile(const AType: string; ASource: TMemIniFile): boolean;  stdcall;


Второй вариант интерфейса
Код: pascal
1.
2.
3.
4.
5.
6.
IConfigController = interface(IInterface)
    procedure Load(const AType: string; ADest: TStrings);overload; stdcall;
    function Save(const AType: string; ASource: TStrings): boolean; overload; stdcall;
    procedure Load(const AType: string; ADest: TMemIniFile);overload; stdcall;
    function Save(const AType: string; ASource: TMemIniFile): boolean; overload; stdcall;
  end;


и объявление в классе
Код: pascal
1.
2.
3.
4.
5.
6.
7.
{IConfigController}
    procedure IConfigController.Load = LoadConfigFile;
    function IConfigController.Save =  SaveConfigFile;
    procedure LoadConfigFile(const AType: string; ADest: TStrings);overload; stdcall;
    function SaveConfigFile(const AType: string; ASource: TStrings): boolean; overload; stdcall;
    procedure LoadConfigFile(const AType: string; ADest: TMemIniFile);overload; stdcall;
    function SaveConfigFile(const AType: string; ASource: TMemIniFile): boolean; overload; stdcall;


Понятно, что компилятор пошлет в пеший тур ибо замыкание функций на интерфейс не корректно.
Именование функций в интерфейсе нужно оставить именно таким. В классе тоже, т.к. он здоровый и всяких load/save там куча
Без костыля в виде отдельного класса никак?
...
Рейтинг: 0 / 0
07.12.2017, 11:45:44
    #39565691
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
Что мешает вместо Load использовать более осмысленное название процедуры (ConfigLoad)?
...
Рейтинг: 0 / 0
07.12.2017, 11:52:20
    #39565700
AX-Class
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
Олег Третьяков,
Т.е., как заменить
Код: pascal
1.
procedure IConfigController.Load = LoadConfigFile;

на
Код: pascal
1.
2.
3.
4.
5.
6.
procedure Load(const AType: string; ADest: TStrings);overload; stdcall;
...
procedure Load(const AType: string; ADest: TStrings);
begin
  LoadConfigFile(AType, ADest);
end;


но, чтоб было меньше букв?
...
Рейтинг: 0 / 0
07.12.2017, 12:08:21
    #39565724
Олег Третьяков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
wadman,
на мой взгляд не комильфо далее будет ConfigController.configLoad. дважды config - как то не айс
AX-Class,
Речь идет о синтаксисе замыкания перегруженных функций в интерфейсе на их псевдонимы реализации в классе. И да, чтоб меньше букв)
...
Рейтинг: 0 / 0
07.12.2017, 12:49:55
    #39565767
GunSmoker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
Олег Третьяков, а зачем в классе нужен именно overload Load/SaveConfigFile?
...
Рейтинг: 0 / 0
07.12.2017, 13:07:09
    #39565791
Олег Третьяков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
GunSmoker,
Именно overload?.. В классе?....
Мм.. не уловил изюмину вопроса.
Я правда уже поломал код и нарисовал класс-костыль.
...
Рейтинг: 0 / 0
07.12.2017, 13:17:38
    #39565800
Олег Третьяков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
GunSmoker,
Пес ними, именами, но сигнатуры разве не должны совпадать в интерфейсе и в классе?
...
Рейтинг: 0 / 0
07.12.2017, 13:55:04
    #39565831
GunSmoker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
Олег Третьяков, я, мож, вопрос не уловил, но:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
    procedure LoadConfigFile1(const AType: string; ADest: TStrings); stdcall;
    function SaveConfigFile1(const AType: string; ASource: TStrings): boolean; stdcall;
    procedure LoadConfigFile2(const AType: string; ADest: TMemIniFile); stdcall;
    function SaveConfigFile2(const AType: string; ASource: TMemIniFile): boolean; stdcall;
    procedure IConfigController.Load = LoadConfigFile1;
    function IConfigController.Save =  SaveConfigFile1;
    procedure IConfigController2.Load = LoadConfigFile2;
    function IConfigController2.Save =  SaveConfigFile2;
...
Рейтинг: 0 / 0
07.12.2017, 13:59:48
    #39565841
Dimonka
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
Ещё можно подумать в другом направлении, например можно сделать класс-адаптер для разных типов источника данных, а Load/Save сделать работающим с адаптером. Тогда в классе достаточно оставить методы Load/Save:
Код: pascal
1.
2.
3.
4.
IConfigController = interface(IInterface)
    procedure Load(const AType: string; ADest: TMyDataSource); stdcall;
    function Save(const AType: string; ASource: TMyDataSource): boolean;  stdcall;
  end;

А уже в TMyDataSource прописать работу с разными источниками данных.
...
Рейтинг: 0 / 0
07.12.2017, 14:06:13
    #39565849
Олег Третьяков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
GunSmoker,
Это разнос на два интерфейса.
Ну да, не уловил.
Хочу реализовать в одном интерфейсе более одного вариантов функции. В классе именовать с префиксом имени интерфейса.
...
Рейтинг: 0 / 0
07.12.2017, 14:32:01
    #39565889
Олег Третьяков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
Dimonka,
Не хотел городить адаптер, видимо придется, с маршрутизацией через QueryInterface. Благо используемого функционала, теперь уже владельца, не много.
офф: торможу с участием, т.к. сегодня баги с электричеством офисе, бесперебойники пищат, приходится выключаться.
...
Рейтинг: 0 / 0
07.12.2017, 14:50:27
    #39565908
Кар-Кар
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
Очевидно не работает.
Может хаком тогда, дублирование. Внутри юнита, где класс реализовывается делаем копипаст здорового интерфейса и..

Код: pascal
1.
2.
3.
4.
5.
6.
7.
IConfigController = interface(IInterface)
['{F4BAACCE-328C-4038-8184-DE1ACECF881E}']
  procedure Load_Strings(const AType: string; ADest: TStrings);overload; stdcall;
  function Save_Strings(const AType: string; ASource: TStrings): boolean; overload; stdcall;
  procedure Load_Ini(const AType: string; ADest: TMemIniFile);overload; stdcall;
  function Save_Ini(const AType: string; ASource: TMemIniFile): boolean; overload; stdcall;
end;

Его и реализуем, наружу хард кастим. Главное чтоб GUID был одинаковым!
...
Рейтинг: 0 / 0
07.12.2017, 15:07:46
    #39565931
Кар-Кар
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
Т.е. будет внутри скрытый интерфейс с тем же GUID и нужным именованием методов:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
IConfigControllerInternal = interface(IInterface)
['{F4BAACCE-328C-4038-8184-DE1ACECF881E}']
  procedure IConfigController_Load(const AType: string; ADest: TStrings);overload; stdcall;
  function IConfigController_Save(const AType: string; ASource: TStrings): boolean; overload; stdcall;
  procedure IConfigController_Load(const AType: string; ADest: TMemIniFile);overload; stdcall;
  function IConfigController_Save(const AType: string; ASource: TMemIniFile): boolean; overload; stdcall;
end;

TMyClass = class(TInterfacedObject, IConfigControllerInternal)
public
  procedure IConfigController_Load(const AType: string; ADest: TStrings);overload; stdcall;
  function IConfigController_Save(const AType: string; ASource: TStrings): boolean; overload; stdcall;
  procedure IConfigController_Load(const AType: string; ADest: TMemIniFile);overload; stdcall;
  function IConfigController_Save(const AType: string; ASource: TMemIniFile): boolean; overload; stdcall;
end;

function CreateConfigController:IInterface;
begin
TConfigController.Create.QueryInterface(IConfigController{IConfigControllerInternal},Result);
end;

exports
CreateConfigController;


А снаружи для человеков будет:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
IConfigController = interface(IInterface)
['{F4BAACCE-328C-4038-8184-DE1ACECF881E}']
  procedure Load(const AType: string; ADest: TStrings);overload; stdcall;
  function Save(const AType: string; ASource: TStrings): boolean; overload; stdcall;
  procedure Load(const AType: string; ADest: TMemIniFile);overload; stdcall;
  function Save(const AType: string; ASource: TMemIniFile): boolean; overload; stdcall;
end;

function CreateConfigController:IConfigController;external 'MyLib.dll';


VMT совпадает, главное держать синхронно оба в случае изменений.
...
Рейтинг: 0 / 0
07.12.2017, 15:34:19
    #39565967
Олег Третьяков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
Кар-Кар,
В топку поддержание синхронности)
Вынес в отдельный класс, имхо меньшее зло
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
TConfigController = class(TComponent,
                            IConfigController)
   public
    procedure Load(const AType: string; ADest: TMemoryStream);overload; stdcall;
    function Save(const AType: string; ASource: TMemoryStream): boolean; overload; stdcall;
    procedure Load(const AType: string; ADest: TStrings);overload; stdcall;
    function Save(const AType: string; ASource: TStrings): boolean; overload; stdcall;
    procedure Load(const AType: string; ADest: TMemIniFile);overload; stdcall;
    function Save(const AType: string; ASource: TMemIniFile): boolean; overload; stdcall;
  end;


в классе-владельце
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
function TBaseClass.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
  if IsEqualGUID(IID, IConfigController) then
  begin
    if Assigned(fConfigController) then
      Result := fConfigController.QueryInterface(IID, Obj)
    else
      Result := E_NOINTERFACE;
    Exit;
  end else
    Result := inherited QueryInterface(IID, Obj);
end;

...
Рейтинг: 0 / 0
07.12.2017, 15:42:08
    #39565980
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
Олег Третьяковв классе-владельцеА почему бы не сделать через property implements? Смысл тот же, а кода меньше. И в новых делфях QueryInterface будет работать в обе стороны
...
Рейтинг: 0 / 0
07.12.2017, 16:04:42
    #39566010
Олег Третьяков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
_Vasilisk_,
Привычка.
Да, можно, согласен.
_Vasilisk_ И в новых делфях QueryInterface будет работать в обе стороны
Эм, интересно. Даже рекурсии не возникает? Можно ссылко с деталями?
...
Рейтинг: 0 / 0
07.12.2017, 17:53:07
    #39566127
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
Олег ТретьяковМожно ссылко с деталями? тынц
...
Рейтинг: 0 / 0
12.12.2017, 10:39:37
    #39568144
Hammer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
Типа так?:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
unit UConfigController;

interface

uses Classes, IniFiles;

type
  IConfigController = interface(IInterface)
    ['{0D874EC8-386A-4CB8-B37B-34FD485BEC98}']
    procedure LoadMemIniFile(const AType: string; ADest: TMemIniFile); stdcall;
    function SaveMemIniFile(const AType: string; ASource: TMemIniFile): boolean; stdcall;
    procedure LoadStrings(const AType: string; ADest: TStrings); stdcall;
    function SaveStrings(const AType: string; ASource: TStrings): boolean; stdcall;
    procedure Load(const AType: string; ADest: TObject); stdcall;
    function Save(const AType: string; ASource: TObject): boolean; stdcall;
  end;

  TConfigController = class(TInterfacedObject,
                            IConfigController)
  private
    procedure LoadMemIniFile(const AType: string; ADest: TMemIniFile); stdcall;
    function SaveMemIniFile(const AType: string; ASource: TMemIniFile): boolean; stdcall;
    procedure LoadStrings(const AType: string; ADest: TStrings); stdcall;
    function SaveStrings(const AType: string; ASource: TStrings): boolean; stdcall;
  public
    procedure Load(const AType: string; ADest: TObject); stdcall;
    function Save(const AType: string; ASource: TObject): boolean; stdcall;
  public
    class function GetConfigController: IConfigController;
  end;

implementation

{ TConfigController }

class function TConfigController.GetConfigController: IConfigController;
begin
  Result := TConfigController.Create;
end;

procedure TConfigController.Load(const AType: string; ADest: TObject);
begin
  if ADest.InheritsFrom(TMemIniFile) then
    LoadMemIniFile(AType, TMemIniFile(ADest))
  else
    if ADest.InheritsFrom(TStrings) then
      LoadStrings(AType, TStrings(ADest))
end;

procedure TConfigController.LoadMemIniFile(const AType: string;
  ADest: TMemIniFile);
begin
//
end;

procedure TConfigController.LoadStrings(const AType: string; ADest: TStrings);
begin
//
end;

function TConfigController.Save(const AType: string; ASource: TObject): boolean;
begin
  Result := False;
  if ASource.InheritsFrom(TMemIniFile) then
    Result := SaveMemIniFile(AType, TMemIniFile(ASource))
  else
    if ASource.InheritsFrom(TStrings) then
      Result := SaveStrings(AType, TStrings(ASource))
end;

function TConfigController.SaveMemIniFile(const AType: string;
  ASource: TMemIniFile): boolean;
begin
  Result := False;
end;

function TConfigController.SaveStrings(const AType: string;
  ASource: TStrings): boolean;
begin
  Result := False;
end;

end.


...
Рейтинг: 0 / 0
12.12.2017, 16:56:48
    #39568474
Олег Третьяков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
Hammer,
Нет. см. выше.
...
Рейтинг: 0 / 0
12.12.2017, 19:37:00
    #39568624
Hammer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
Олег ТретьяковHammer,
Нет. см. выше.
Хозяин-барин.
Надеюсь, что он в курсе того, что TComponent не поддерживает подсчет ссылок.
...
Рейтинг: 0 / 0
12.12.2017, 21:00:40
    #39568671
Олег Третьяков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейс с перегруженными функциями и его реализация
Hammer,
Есно)
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Интерфейс с перегруженными функциями и его реализация / 21 сообщений из 21, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]