Внедрение зависимостей в C ++

голоса
23

Это также вопрос , который я спросил комментарий в одном из Мисько Hevery в Google переговоров , что было дело с инъекцией зависимостей , но он был похоронен в комментариях.

Интересно, как можно шаг завод / строитель проводки зависимостей могут вместе работать в C ++.

То есть у нас есть класс А, который зависит от B. Застройщик будет выделять B в куче, передать указатель на B в конструкторе в то же время выделения в куче и возвращает указатель на A.

Кто очищает потом? Это хорошо, чтобы строитель убирать за это сделано? Это, кажется, правильный метод, так как в разговоре он говорит, что строитель должен объекты настройки, которые, как ожидается, иметь такой же срок службы или, по крайней мере, зависимостей имеют более продолжительный срок службы (у меня тоже есть вопрос о том, что). Что я имею в виду в коде:

class builder {
public:
    builder() :
        m_ClassA(NULL),m_ClassB(NULL) {
    }
    ~builder() {
        if (m_ClassB) {
            delete m_ClassB;
        }
        if (m_ClassA) {
            delete m_ClassA;
        }
    }
    ClassA *build() {
        m_ClassB = new class B;
        m_ClassA = new class A(m_ClassB);
        return m_ClassA;
    }
};

Теперь, если есть зависимость, которая, как ожидается, будет длиться дольше, чем время жизни объекта мы инъекционный его в (скажет ClassC, что зависимость) Я понимаю, что мы должны изменить метод сборки на что-то вроде:

ClassA *builder::build(ClassC *classC) {
    m_ClassB = new class B;
    m_ClassA = new class A(m_ClassB, classC);
    return m_ClassA;
}

Какой ваш предпочтительный подход?

Задан 09/12/2008 в 15:26
источник пользователем
На других языках...                            


8 ответов

голоса
13

Это речь идет о Java и инъекции зависимостей.

В C ++ мы стараемся НЕ передавать RAW указатели вокруг. Это происходит потому, что RAW указатель не имеет собственностей семантики , связанную с ним. Если у вас нет права собственности , то мы не знаем , кто несет ответственность за очистку объекта.

Я считаю , что большинство инъекций в зависимости от времени осуществляется с помощью ссылок в C ++.
В тех редких случаях , когда вы должны использовать указатели, завернуть их в станд :: unique_ptr <> или станд :: shared_ptr <> в зависимости от того, как вы хотите , чтобы управлять собственностью.
В случае , если вы не можете использовать C ++ 11 функций, используйте станд :: auto_ptr <> или повышение :: shared_ptr <>.

Я хотел бы также отметить, что C ++ и Java стили программирования теперь настолько расходящиеся, что применение стиля одного языка на другой, неизбежно приведет к катастрофе.

Ответил 09/12/2008 в 15:47
источник пользователем

голоса
9

Это интересно, DI в C ++ с помощью шаблонов:

http://adam.younglogic.com/?p=146

Я думаю, что автор делает правильные шаги, чтобы не переводить Java DI в C ++ слишком буквально. Стоит прочитать.

Ответил 23/12/2009 в 02:08
источник пользователем

голоса
6

Я недавно был укушен DI ошибка. Я думаю , что это решает много проблем сложности, особенно автоматизированной часть. Я написал прототип , который позволяет использовать DI в симпатичной образом C ++, или по крайней мере я так думаю. Вы можете посмотреть на пример кода здесь: http://codepad.org/GpOujZ79

Не Вещи, которые, очевидно, отсутствует: нет обзорного, нет привязки интерфейса к реализации. Последнее довольно легко решить, первый, я понятия не имею.

Я был бы признателен, если кто-нибудь здесь есть мнение о коде.

Ответил 10/05/2010 в 17:39
источник пользователем

голоса
3

Используйте RAII.

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

shared_ptr <> может это сделать; второй аргумент в конструкторе может быть функциональным объектом, который знает, как удалить объект.

Ответил 09/12/2008 в 17:40
источник пользователем

голоса
2

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

Иногда крест зависимость неизбежна, и нет никакой ясной собственности. Так, например, (м) экземпляры А собственный (п) экземпляры B, а также некоторые случаи B могут принадлежать кратным As. В этом случае, лучший подход заключается в применении подсчета ссылок В, в аналогии с COM подсчета ссылок. Любые функции, которые принимают во владение B * необходимо сначала увеличить количество ссылок, а также уменьшить его при отпускании владения.

Я также не использовать повышение :: shared_ptr, поскольку это создает новый тип (shared_ptr и B * стать два различных типа). Я обнаружил, что она приносит больше головной боли, когда я добавляю методы.

Ответил 23/12/2009 в 17:04
источник пользователем

голоса
2

В C ++, как правило, когда вы сделали все правильно, вам не нужно писать деструкторы вообще в большинстве случаев. Вы должны использовать смарт-указатели, чтобы удалить вещи автоматически. Я думаю, строитель не похож на владельца экземпляров CLASSA и ClassB. Если вам не нравится использовать смарт-указатели, вы должны думать о время объектов жизни и их владельцах.

Ответил 09/12/2008 в 16:14
источник пользователем

голоса
2

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

Не Лично я бы сказал, что нет: объект, в котором зависимость впрыскивается будет убирать потом. Попытка сделать это через строитель означает, что застройщик должен будет жить дольше, чем как зависимость и объект, в который он вставляется. Это вызывает больше проблем, чем решает, на мой взгляд, потому что строитель не служит никакой более полезной цели после того, как конструкция с инъекцией в зависимости завершена.

Ответил 09/12/2008 в 15:33
источник пользователем

голоса
1

Вы также можете проверить Injection FFEAD зависимостей . Она обеспечивает DI на линиях Spring для JAVA и имеет не навязчивый способ борьбы с вещами. Она также имеет много других важные функции , такие как встроенный AJAX поддержка, отражение, сериализация, C ++ интерпретатор, бизнес - компоненты C ++, ОРМ, сообщения, веб-службы, Thread-пулы и сервер приложений , который поддерживает все эти функции.

Ответил 10/08/2010 в 08:31
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more