Ленивая загрузка / динамическое связывание против безопасности

Прежде всего, я думаю, что термин, который я хочу, не является ни «отложенной загрузкой», ни «динамическим связыванием». Я не знаю правильный термин, но я отредактирую этот вопрос, когда сделаю это.

Я соединяю объекты обработки для создания потока данных A-> B:

Способ 1: подключиться во время инстанции
Код: https://ideone.com/Rsqabi

class Consumer {
public:
virtual void consume(int data) = 0;
};

class A {
public:
A(Consumer& consumer) : consumer_(consumer) {}
void process(int data) { consumer_.consume(data); }
private:
Consumer& consumer_;
};

class B : public Consumer {
public:
B() {}
void consume(int data) { /* consume data */ }
};

Мне нужно иметь экземпляр Consumer под рукой, чтобы создать экземпляр A:

int main() {
B* b_ = new B();
A a_ = A(*b_);
a_.process(5);
return 0;
}

Способ 2: подключиться после создания экземпляра
Код: https://ideone.com/5ij0yZ

Что я действительно хочу, так это выбрать своего Потребителя после создания A:

class A {
public:
A() {}
void attachConsumer(Consumer* consumer) { consumer_ = consumer; }
void process(int data) {
// must always check consumer_ here!
consumer_->consume(data);
}
private:
Consumer* consumer_;
};

а потом:

int main() {
A a_ = A();
// ... for reasons I won't tell you, B must be created later than A ...
B* b_ = new B();
a_.attachConsumer(b_);
a_.process(5);
return 0;
}

Лучшая модель?

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

Метод 2 хорош, потому что я могу выбрать в будущем, какой Потребитель присоединить (или повторно присоединить, если состояние считается безопасным). Это плохо, потому что указатели опасны.

Есть ли метод 3, который удовлетворяет плюсам обеих моделей? Где мне не всегда нужно проверять, является ли мой потребитель действительным и подключенным, но это также позволяет динамическое подключение?

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

0

Решение

Способ 1 приводит к утечке памяти, потому что нужно освободить Consumer, после того как A будет удален. Ссылка будет действительной, но она не уничтожит объект, когда будет уничтожена, поэтому вам все равно нужно «помнить» об освобождении B, что устраняет преимущество 1-го метода.

Используйте std :: shared_ptr для удержания B, если вы боитесь забыть освободить B и хотите быть уверенным, что держите его.

И не забудьте добавить «явный» в конструктор с одним параметром.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector