Форум программистов, компьютерный форум, киберфорум
C/C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/21: Рейтинг темы: голосов - 21, средняя оценка - 4.57
0 / 0 / 0
Регистрация: 30.04.2011
Сообщений: 68

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

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

Студворк — интернет-сервис помощи студентам
Поясните, при реализации функции интерфейса ниже, возникли вопросы:
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
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.09.2013, 18:55
Ответы с готовыми решениями:

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

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

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

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

Добавлено через 5 минут
для любопытства
https://www.cyberforum.ru/com-... ost3538077
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
05.09.2013, 01:06
Цитата Сообщение от 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
Модератор
 Аватар для vxg
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
05.09.2013, 10:09
Цитата Сообщение от Убежденный Посмотреть сообщение
Правильно будет сделать примерно так
или лучше так)
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  [ТС]
Цитата Сообщение от 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
Модератор
 Аватар для vxg
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
05.09.2013, 13:25
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
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
06.09.2013, 09:41
Цитата Сообщение от vxg Посмотреть сообщение
лучше приземленно озвучьте про агрегаты - что за звери?
Приземленно, агрегация - это когда один COM-объект включает в себя другой,
причем этот другой знает о включении и ведет себя соответствующим образом.
Например, через IUnknown на включаемый класс можно получить IUnknown
внешнего класса.

Все это хорошо описано в "Основы COM" (Д. Роджерсон).
1
Модератор
 Аватар для vxg
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
06.09.2013, 10:07
Цитата Сообщение от Убежденный Посмотреть сообщение
Все это хорошо описано в "Основы COM" (Д. Роджерсон).
скачал. да, интересно.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
06.09.2013, 10:07
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Загрузка PNG-файла с альфа-каналом с помощью библиотеки SDL3_image на Android
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru