0 / 0 / 0
Регистрация: 30.04.2011
Сообщений: 68
1

Правильная реализация интерфейса фабрики классов

04.09.2013, 18:55. Показов 3839. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Поясните, при реализации функции интерфейса ниже, возникли вопросы:
1) зачем нужна фабрика
2) CreateInstance вернет указатель на интерфейс ppv только в случае, если он ранее был выделен в память, или создаст новый экземпляр?
PS не закидывайте белками, я только начал разбираться в COM и чуть запутался со всем. Буду рад любой помощи

C++
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
HRESULT __stdcall CAddFactory::CreateInstance(IUnknown* pUnknownOuter,
                                           const IID& iid,
                                           void** ppv) 
    {
    //
    //This method lets the client manufacture components en masse
    //The class factory provides a mechanism to control the way
    //the component is created. Within the class factory the 
    //author of the component may decide to selectivey enable
    //or disable creation as per license agreements 
    //
    //
 
    // Cannot aggregate.
    if (pUnknownOuter != NULL)
        {
        return CLASS_E_NOAGGREGATION ;
        }
 
    //
    // Create an instance of the component.
    //
    CAddObj* pObject = new CAddObj ;
    if (pObject == NULL)
        {
        return E_OUTOFMEMORY ;
        }
 
    //
    // Get the requested interface.
    //
    return pObject->QueryInterface(iid, ppv) ;
    }
 
 
HRESULT __stdcall CAddFactory::LockServer(BOOL bLock) 
    {
    return E_NOTIMPL;
    }
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.09.2013, 18:55
Ответы с готовыми решениями:

Правильная стройка классов
Здравствуйте! Пытаюсь реализовать MVC на С++. Застрял на начальном этапе - создание M, V, C. Вот...

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

[MFC] CObject::Serialize(...) А фабрики классов нету?
Вот собственно вопрос... Я могу прочитать из архива объект, когда знаю его фактический класс. ...

Создание экземпляров COM объектов с использованием фабрики классов
Доброго времени суток! Помогите разобраться, пожалуйста. Есть сторонний ActiveX компонент....

7
Модератор
3401 / 2172 / 353
Регистрация: 13.01.2012
Сообщений: 8,413
04.09.2013, 22:56 2
1 фабрика нужна для того что бы производить объекты. как еще их произвести если программа оперирует только указателями на абстрактный класс (интерфейсами)? кто-то должен создать реальный объект расширяющий этот класс. этим занимается фабрика. это как бы вызов new my_object только с более сложным поведением. каким именно - решать разработчику объекта. в простейшем случае это new my_object. в другом случае объект может быть один и все клиенты получат указатель на этот единственный объект. и т. п.
2 объект создает фабрика, функция возвращает указатель на объект. если точнее на интерфейс.

Добавлено через 5 минут
для любопытства
https://www.cyberforum.ru/com-... ost3538077
0
Ушел с форума
Эксперт С++
16478 / 7441 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
05.09.2013, 01:06 3
Цитата Сообщение от voipp Посмотреть сообщение
1) зачем нужна фабрика
Фабрика - это отделение функциональности объекта от способа его создания.
Например, можно в CreateInstance каждый раз создавать новые объекты, а можно
возвращать указатель на уже существующий объект, оставляя его в одном экземпляре.
Во втором случае получится COM-синглтон. Но для клиента все это прозрачно.

Цитата Сообщение от voipp Посмотреть сообщение
C++
1
2
3
4
5
//
// Create an instance of the component.
//
CAddObj* pObject = new CAddObj ;
if (pObject == NULL)
new не возвращает NULL, он кидает исключение std::bad_alloc.

Вообще, весь фрагмент не совсем четкий. Например, что если созданный в CreateInstance
объект CAddObj не поддерживает запрошенный интерфейс ? Временный объект следует
удалить, но здесь этого не происходит и в результате возникает утечка.
Правильно будет сделать примерно так:
C++
1
2
3
4
5
CAddObj* pObject = new CAddObj; // Ref count = 0.
pObject->AddRef(); // Ref count = 1.
HRESULT const RetValue = pObject->QueryInterface(iid, ppv);
pObject->Release();
return RetValue;
Здесь если интерфейс поддерживается, QueryInterface установит дополнительную
ссылку на объект, поэтому он выживет после Release. А если не поддерживается, то на
вызове Release количество ссылок будет равно нулю и объект будет уничтожен.
Разумеется, все это справедливо лишь в случае, если работа со ссылками реализована
правильно, например объект создается с нулевым ref counter.
0
Модератор
3401 / 2172 / 353
Регистрация: 13.01.2012
Сообщений: 8,413
05.09.2013, 10:09 4
Цитата Сообщение от Убежденный Посмотреть сообщение
Правильно будет сделать примерно так
или лучше так)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* [local] */ HRESULT __stdcall CoMyObjectClassFactory::CreateInstance(
    /* [unique][in] */ IUnknown *pUnkOuter,
    /* [in] */ REFIID riid,
    /* [iid_is][out] */ void **ppvObject)
{
    if (pUnkOuter) return CLASS_E_NOAGGREGATION;
 
    if (!ppvObject) return E_INVALIDARG;
 
    CoMyObject *p = new(std::nothrow) CoMyObject;
    if (!p) return E_OUTOFMEMORY;
 
    HRESULT res = p->QueryInterface(riid, ppvObject);
    if (FAILED(res)) delete p;
 
    return res;
}
лучше приземленно озвучьте про агрегаты - что за звери?
0
0 / 0 / 0
Регистрация: 30.04.2011
Сообщений: 68
05.09.2013, 10:57  [ТС] 5
Цитата Сообщение от vxg Посмотреть сообщение
или лучше так)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* [local] */ HRESULT __stdcall CoMyObjectClassFactory::CreateInstance(
    /* [unique][in] */ IUnknown *pUnkOuter,
    /* [in] */ REFIID riid,
    /* [iid_is][out] */ void **ppvObject)
{
    if (pUnkOuter) return CLASS_E_NOAGGREGATION;
 
    if (!ppvObject) return E_INVALIDARG;
 
    CoMyObject *p = new(std::nothrow) CoMyObject;
    if (!p) return E_OUTOFMEMORY;
 
    HRESULT res = p->QueryInterface(riid, ppvObject);
    if (FAILED(res)) delete p;
 
    return res;
}
лучше приземленно озвучьте про агрегаты - что за звери?
Ниииипоняяяятно
0
Модератор
3401 / 2172 / 353
Регистрация: 13.01.2012
Сообщений: 8,413
05.09.2013, 13:25 6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* [local] */ HRESULT __stdcall CoMyObjectClassFactory::CreateInstance(
    /* [unique][in] */ IUnknown *pUnkOuter,
    /* [in] */ REFIID riid,
    /* [iid_is][out] */ void **ppvObject)
{
    if (pUnkOuter) return CLASS_E_NOAGGREGATION; //если от нас хотят агрегат - мы не знаем что это такое, выбрасываем ошибку
 
    if (!ppvObject) return E_INVALIDARG; //если аргумент плохой - выбрасываем ошибку
 
    CoMyObject *p = new(std::nothrow) CoMyObject; //создаем объект (должен быть производным от запрашиваемого интерфейса)
    if (!p) return E_OUTOFMEMORY; //если не удалось - выбрасываем ошибку
 
    HRESULT res = p->QueryInterface(riid, ppvObject); //получаем интерфейс (если объект не найдет у себя интерфейс он вернет ошибку)
    if (FAILED(res)) delete p; //если объект вернул ошибку - удаляем его
 
    return res; //возвращаем результат вызова функции получения интерфейса
}
0
Ушел с форума
Эксперт С++
16478 / 7441 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
06.09.2013, 09:41 7
Цитата Сообщение от vxg Посмотреть сообщение
лучше приземленно озвучьте про агрегаты - что за звери?
Приземленно, агрегация - это когда один COM-объект включает в себя другой,
причем этот другой знает о включении и ведет себя соответствующим образом.
Например, через IUnknown на включаемый класс можно получить IUnknown
внешнего класса.

Все это хорошо описано в "Основы COM" (Д. Роджерсон).
1
Модератор
3401 / 2172 / 353
Регистрация: 13.01.2012
Сообщений: 8,413
06.09.2013, 10:07 8
Цитата Сообщение от Убежденный Посмотреть сообщение
Все это хорошо описано в "Основы COM" (Д. Роджерсон).
скачал. да, интересно.
0
06.09.2013, 10:07
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.09.2013, 10:07
Помогаю со студенческими работами здесь

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

MsSql: Правильная организация интерфейса
Доброго времени суток, обитатели форума.Требуется ваша помощь. Делаю интерфейс для бд книжного...

Правильная настройка интерфейса на ДНС-сервере
Всем привет) Такой вопорос. В организации есть два домен-контроллера. Оба - днс-серверы. К каждому...

Вынести методы из классов Panel и PictureBox (явная реализация методов базовых абстрактных классов)
Тема: Множественное наследование. Явная реализация методов базовых абстрактных классов. Как...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru