2014-11-15 3 views
0

Я пишу макросы для отладки системыКак вернуть ссылку на новый объект без утечек памяти? C++

У меня есть перегруженный прикован оператор <<(MessageAssembler& target,message_type msg) (message_type) является параметром шаблона для оператора

Он добавляет msg к target «s внутренним переменному типа QTextStream.

Оператор +=(MessageAssembler& result) из MessageAssembler проходов result «S потока в функции, которая обрабатывает его на основе параметров result.

Я хочу сделать что-то вроде этого:

#define FATAL(facility) NLog::assembler+=MessageAssembler(Log::fatal_sev,facility)<< __FILE__<<":"<<__LINE__ 

(NLog::assembler является статическим переменным типом MessageAssembler)

Он должен определить объект выходных, в позволяет пользователю добавить свое собственное сообщение для вывода на используя

FATAL(some_facility)<<"custom message"<<ObjectWhichCanBePassedToQTextStream()<<AnotherObject(); 

Но MessageAssembler(Log::fatal_sev,facility) производит a reference to temporary ошибку.

Это

MessageAssembler& MessageAssembler::get_instance(Log::Severity _msg_sev,Log::Facility _msg_fac) 
{ 
    MessageAssembler tmp(_msg_sev,_msg_fac); 
    return tmp; 
} 

будет возвращать ссылку на несуществующий объект;

Это

MessageAssembler& MessageAssembler::get_instance(Log::Severity _msg_sev,Log::Facility _msg_fac) 
{ 
    return new MessageAssembler tmp(_msg_sev,_msg_fac); 
} 

вызовет утечку памяти

Это

QScopedPointer<MessageAssembler> MessageAssembler::get_instance(Log::Severity _msg_sev,Log::Facility _msg_fac) 
{ 
    return QScopedPointer<MessageAssembler>(new MessageAssembler tmp(_msg_sev,_msg_fac)); 
} 

не будет работать, потому что QScopedPointer не может быть передан по значению

Я не уверен, если сохранение второй статической переменной MessageAssembler chain_starter; является потокобезопасной.

У меня есть не только FATAL макрос, поэтому программа не будет всегда прервана после вызова.

Как я могу вернуть ссылку на новый MessageAssembler?

EDIT: У меня проблема была решена путем установки сторонней библиотеки для интеллектуального указателя, а именно, yasper. Общее решение предложено πάντα ῥεῖ.

ответ

3

Самый краткий ответ:

Не делайте это с помощью сырых указателей! Вместо этого используйте C++ smart pointer features.

Самая простая реализация, похоже, создает экземпляр std::unique_ptr<MessageAssembler> и возвращает этот. Вызывающий клиент получит право собственности на созданный экземпляр, и он будет удален автоматически, как только ссылка исчезнет из области видимости.

+0

Есть ли способ сделать это без 'unique_ptr'? Поскольку QtCreator в Ubuntu создает 'error: 'unique_ptr' в пространстве имен 'std' не называет тип static std :: unique_ptr '. Я не уверен, убедил ли я других изменить настройки компилятора для этой проблемы и что изменение настроек возможно. – user2136963

+2

@ user2136963 Qt обычно хорошо сочетается с указанием '-std = C++ 11', хотя вы не сузили свой вопрос, ограничиваясь такими соображениями. –

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