2009-05-29 6 views
4

Одна из библиотек, которые мы используем для нашего продукта, использует одноэлементный доступ для доступа к нему. Я уверен, что он реализован как статический экземпляр (он не является открытым исходным кодом). Это хорошо работает для одного приложения документа, но в нашем приложении может быть загружено более одного документа. Я предполагаю, что доступ к экземпляру написано что-то вроде этого:Создание нескольких экземпляров глобальной статики в C++?

Instance* getInstance() { 
    static Instance* inst = new Instance(); 
    return inst; 
} 

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

Я попросил поставщика реализовать некоторый тип токена сеанса, поэтому я могу иметь несколько параллельных экземпляров, но они большие и мы маленькие.

Cory

Edit:

  • машина является Windows
  • машину
  • глобальный статический в основном большой завод. Я хочу сессионную фишку какого-либо типа, так что я могу легко сказать, «освободить все ресурсы этой сессии» (нет никакого способа, чтобы повторно инициализировать глобальную статику, что я знаю)

Вместо того, чтобы попробовать некоторые нечестные махинации чтобы получить то, что я хочу, я собираюсь обернуть все это своим классом и добавить ключ сеанса для каждого получателя. Внутри я буду следить за тем, что было выделено, добавив мой собственный метод выпуска для возврата ресурсов. Это неоптимально по многим причинам, но я не могу придумать лучшего представления.

Спасибо всем за отличную обратную связь.

+0

На какой платформе вы работаете? – Skrymsli

+4

Вот почему синглеты злы. Если это действительно серьезно, то для чего может быть только один объект, он не должен быть одиночным. Пусть кто-то другой решит, сколько экземпляров объекта есть. –

ответ

1

Единственное, что я могу думать о том, чтобы подклассы, если вы достаточно удачливы иметь одноплодный класс определяется как:

class Document { 
public: 
    static Document* getInstance() { 
     static Document inst; 
     return &inst; 
    } 
    virtual ~Document(); 
protected: 
    Document(); 
private: 
    struct Impl; 
    Impl *pImpl; 
}; 

Если вы можете унаследовать его и подкласс будет иметь доступ к конструктор, то вы можете создать instanceable подкласс, как:

class MyDocument: public Document { 
public: 
    MyDocument(): Document() { 
    } 
}; 

Это не может быть полностью безопасным, так как реализатор, возможно, сделали некоторые неприятные предположения. Но это идея или какой-то подход, который может иметь некоторый шанс работать. Если повезет, продавец может поддаться этому варианту, если вы упомянуте об этом ... удачи.

+0

Мне нравится ваша идея подкласса. Вместо публичного наследования я собираюсь использовать композицию для обертывания глобальной статики, и я буду менять интерфейс, чтобы добавить поддержку токена сеанса. Спасибо за ответ. – criddell

4

К сожалению, я не вижу недостатка в ваших рассуждениях. Продавец принял решение, и вы связаны им. Он принял решение по одному экземпляру для каждого процесса, поэтому, если вам нужно несколько экземпляров, вы должны иметь несколько процессов со всем, что влечет за собой.

Конечно, если вы предполагаете, что его решение ограничить является произвольным, и для этого нет веской причины, вы можете попытаться его взломать. Путь к началу этого пути состоит в том, чтобы выполнить дезадаптирование/сборку в отладчике. Если вы можете подтвердить, что его фабрика экземпляров работает точно так, как вы это сделали, вы можете без сомнения взломать альтернативу, которая позволяет создавать несколько экземпляров.

Но, конечно же, огромный риск при таком подходе заключается в том, что каждая строка кода в кодовой базе поставщика, которая полагается на его решение иметь один экземпляр, - это временная бомба, готовая взорваться в вашем лице. Этот код невидим для вас. Готовы ли вы ставить, что таких строк нет? Я знаю, что Клинт Иствуд сказал бы в такой ситуации; «Ты чувствуешь себя счастливым панком, хорошо?» :-)

5

Даже если бы вы смогли решить эту конкретную проблему, когда все произошло в-proc, я был бы обеспокоен тем, что эта проблема с одним ядром является лишь верхушкой айсберга. Очевидно, что библиотека не была разработана для вашего сценария.

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

2

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

Возможно, если вы опишете свою проблему более подробно, возможны другие подходы. Трудно сказать, на основе предоставленной информации. Что делает объект singleton? Зачем вам нужны несколько экземпляров?

1

За исключением материалов промежуточного процесса, которые вы предложили, лучший взлом, который я могу придумать, - это копирование dll в новый файл и вручную загрузить новую dll и импортировать все функции, которые вы используете для каждого создаваемого вами экземпляра.

Надеюсь, это означает, что статические переменные не будут конфликтовать между разными экземплярами, поскольку они технически не находятся в одной и той же DLL. Однако в этом решении есть много плохого, например, весь код в dll, клонированный для каждой версии, и вы не сможете использовать библиотеку импорта, но вам нужно загрузить DLL и импортировать все функции вручную.

Смежные вопросы