Заводской класс C ++ / CX для предоставления перегруженных конструкторов с одинаковым количеством аргументов

Я новичок в C ++ / CX, IDL и WRL, и я столкнулся с проблемой. Я не уверен, есть ли ошибка в моем коде или это ограничение дизайна.

У меня есть IDL, который определяет интерфейс IInspectable и его класс времени выполнения, а также класс фабрики, который может предоставлять настраиваемый конструктор. Файл выглядит примерно так:

interface IFoo;    
runtimeclass Foo;
interface IFooFactory;    
[uuid(8543FE719-3F40-987B-BB67-6FD499210BCA), version(0.1), exclusiveto(Foo)]    
interface IFooFactory : IInspectable    
{        
    HRESULT CreateInt32Instance([in] __int32 value, [out][retval]Foo **ppFoo);
    HRESULT CreateInt64Instance([in] __int64 value, [out][retval]Foo **ppFoo);
}    

[uuid(23017380-9876B-40C1-A330-9B6AE1263F5E), version(0.1), exclusiveto(Foo)]
interface IFoo : IInspectable    
{
    HRESULT GetAsInt32([out][retval] __int32 * value);
    HRESULT GetAsInt64([out][retval] __int64 * value);
}

[version(0.1), activatable(0.1), activatable(IFooFactory, 0.1)]    
runtimeclass Foo
{
    [default] interface IFoo;
}

Сам код тривиален, ключевая часть состоит в том, что в определении IFooFactory у меня есть две функции, которые будут проецироваться на конструкторы класса Foo. У этих двух функций одинаковое количество аргументов, но разные типы.

Когда я пытаюсь скомпилировать этот IDL, компилятор жалуется, что:

Более одного фабричного метода с одинаковым количеством аргументов в проектируемых конструкторах.

Я довольно долго искал в Интернете, но не нашел ничего, что упоминало бы об этой проблеме. Разве в этой ситуации недопустимы перегруженные конструкторы с одинаковым количеством аргументов? Если это разрешено, как мне изменить этот IDL? Если нет, могу ли я что-нибудь использовать?


person DiamRem    schedule 24.06.2015    source источник


Ответы (1)


Перегруженные конструкторы с одинаковым количеством аргументов недопустимы, поскольку языки с динамической типизацией (например, JavaScript) не знают, какой конструктор использовать.

Стандартный подход - использовать именованные статические методы.

[uuid(....), version(...), exclusiveto(Foo)]
interface IFooStatics : IInspectable    
{        
    HRESULT FromInt32([in] INT32 value, [out, retval] Foo** result);
    HRESULT FromInt64([in] INT64 value, [out, retval] Foo** result);
}

[version(...)]
/* not activatable */
[static(IFooStatics)]
runtimeclass Foo
{
    [default] interface IFoo;
}

Вы бы тогда сказали

// C++
Foo^ foo1 = Foo::FromInt32(int32Variable);
Foo^ foo2 = Foo::FromInt64(int64Variable);

// C#
Foo foo1 = Foo.FromInt32(int32Variable);
Foo foo2 = Foo.FromInt64(int64Variable);

// JavaScript
var foo1 = Foo.fromInt32(var1);
var foo2 = Foo.fromInt64(var2);
person Raymond Chen    schedule 24.06.2015
comment
Большое спасибо! Некоторое время это беспокоило. - person DiamRem; 24.06.2015