Как объявить и определить Poco Logger?

Я использую отличный фреймворк Poco для ведения журнала. В настоящее время я определяю Logger и LogStream следующим образом в своих заголовочных файлах:

#Foo.h

....

class Foo
{
    private:
        Poco::Logger &logger = Poco::Logger::get("Foo");
        Poco::LogStream logStream{ logger };

}; 

Это служило очень хорошо, пока я не начал использовать буст :: ди. Когда я использую Boost Injector, чтобы создать такой объект для Foo,

injector.create<Foo>();

Я получаю сообщение об ошибке компилятора,

attempting to reference a deleted function

Однако, если я удалю определение LogStream, я не получу ошибку компилятора. Можно ли объявить LogStream в заголовке, не определяя его? Я новичок в С++, и я был бы рад, если бы кто-нибудь мог указать, что я здесь делаю неправильно и как это сделать правильно. Спасибо большое.

Вероятно, ваши экземпляры Foo копируются, но базовым классом Poco::LogStream является std::ostream, который не может быть скопирован, поэтому ваши экземпляры Foo не могут быть скопированы. Чтобы избежать этой проблемы, вы можете сделать logStream своего рода умным указателем, std::shared_ptr или Poco::SharedPtr.

rafix07 17.07.2019 07:24

Спасибо @rafix07, что нашли время написать это. Я попробую ваше предложение.

James Selvakumar 18.07.2019 10:12

Вам не нужно хранить Poco::Logger &logger как член данных этого класса (ссылки не могут быть скопированы, поэтому оператор присваивания копирования по умолчанию не может быть сгенерирован). Вы могли бы сделать Poco::SharedPtr<Poco::LogStream> logStream{new Poco::LogStream(Poco::Logger::get("Foo"))};. Вызовите Logger::get и передайте возвращаемое значение в ctor Poco::LogStream.

rafix07 18.07.2019 10:15

Привет @ rafix07, память не будет управляться автоматически при использовании «нового», не так ли? Нужно ли нам использовать «удалить» в dtor?

James Selvakumar 22.07.2019 10:17

Привет, SharedPtr контролирует время жизни LogStream, вы не делаете это вручную.

rafix07 22.07.2019 10:43

Привет @ rafix07, большое спасибо за ваши предложения. Я попробовал, и это сработало. Можете ли вы опубликовать это как ответ?

James Selvakumar 22.07.2019 11:09
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
302
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Экземпляры Foo не могут быть скопированы по двум причинам:

1) logger является ссылкой, ссылка должна быть инициализирована при создании Foo, поэтому единственный способ для этого нужно использовать конструкторы. Компилятор не может сгенерировать операцию копирования присваивания. Так что Foo f1,f2; f1 = f2; не может работать.

2) Базовым классом LogStream является std::ostream, в котором отключены операции копирования.

Решение: убрать logger как элемент данных, здесь он лишний, потому что мы можем вызвать Poco::Logger, пока LogStream инициализирован.

class Foo {
    //...
    Poco::SharedPtr<Poco::LogStream> logStream{
        new Poco::LogStream(Poco::Logger::get("Foo"))};
};

Чтобы сделать Foo копируемым, вы можете использовать Poco::SharedPtr.

Будет ли какое-либо влияние, если вместо этого будет использоваться std:shared_ptr?

James Selvakumar 23.07.2019 03:54

Вы можете легко использовать std::shared_ptr здесь. Нет никакой разницы.

rafix07 23.07.2019 05:52

Большое спасибо @rafix07. Прекрасно работает.

James Selvakumar 24.07.2019 06:09

Другие вопросы по теме