Russian Qt Forum

Qt => Вопросы новичков => Тема начата: fisenkdima от Апрель 09, 2013, 05:57



Название: Инициализация shared_ptr нулевым указателем
Отправлено: fisenkdima от Апрель 09, 2013, 05:57
Я понимаю, что это не Qt, а чистый С++, но надеюсь, что за вопросы по данной тематике здесь не карают.
А проблема следующая. Есть некий абстрактный класс( abstractFoo ). Есть shared_ptr<abstractFoo> в качестве статического поля некого третьего класса Baz.
Задача его проинициализировать нулевым указателем (ну, в процессе работы предполагается его заменить на нормальный).
Код:
std::tr1::shared_ptr<abstractFoo> Baz::staticField( nullptr );

на подобный код выдаёт следующую ошибку:
ошибка: no matching function for call to 'std::tr1::shared_ptr<BasedKeyGeneratorFunctionOfPacketOfBits>::shared_ptr(std::nullptr_t)'

Вопрос. Как правильно инициализировать переменную shared_ptr<T> нулевым указателем?


Название: Re: Инициализация shared_ptr нулевым указателем
Отправлено: alex312 от Апрель 09, 2013, 07:20
Уважаемый, задавая подобные вопросы, неплохо бы указывать что за компилятор и версия Qt, а также прикладывать к посту минимальный проект для тестирования.


Название: Re: Инициализация shared_ptr нулевым указателем
Отправлено: Vass от Апрель 09, 2013, 08:17
Вопрос. Как правильно инициализировать переменную shared_ptr<T> нулевым указателем?
Кастовать nullptr.
Код:
std::tr1::shared_ptr<abstractFoo> Baz::staticField(static_cast<abstractFoo *>(nullptr));

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


Название: Re: Инициализация shared_ptr нулевым указателем
Отправлено: alex312 от Апрель 09, 2013, 10:34
Соверешенно не причем здесь.
Причем, нипричем ... , но вот код, который работает без всяких кастований:
Код
C++ (Qt)
#include <iostream>
#include <memory>
 
class AbstractClass
{
public:
   virtual void makeSomething() = 0;
};
 
class DerivFromAbstract : public AbstractClass
{
   virtual void makeSomething()
   {
       std::cout<<"Make somesing from DerivFromAbstract"<<std::endl;
   }
};
 
class WithAbstractSmartPtr
{
public:
   static std::shared_ptr<AbstractClass> p1;
};
 
//std::shared_ptr<AbstractClass> WithAbstractSmartPtr::p1 = std::shared_ptr<AbstractClass>(nullptr);
std::shared_ptr<AbstractClass> WithAbstractSmartPtr::p1(nullptr);
 
int main()
{
   WithAbstractSmartPtr tst;
 
   if( !tst.p1 )
       std::cout<<"wrong pointer"<<std::endl;
   else
       {
           std::cout<<"good pointer"<<std::endl;
           tst.p1->makeSomething();
       }
   WithAbstractSmartPtr::p1 = std::shared_ptr<AbstractClass>(new DerivFromAbstract);
   if( !tst.p1 )
       std::cout<<"wrong pointer"<<std::endl;
   else
       {
           std::cout<<"good pointer"<<std::endl;
           tst.p1->makeSomething();
       }
   return 0;
}
 
проверено для msvc2010 и gcc4.7.2(mingw)


Название: Re: Инициализация shared_ptr нулевым указателем
Отправлено: mutineer от Апрель 09, 2013, 10:35
Конструктор shared_ptr без параметров разве не создает пустой указатель?


Название: Re: Инициализация shared_ptr нулевым указателем
Отправлено: fisenkdima от Апрель 10, 2013, 04:54
Уважаемый, задавая подобные вопросы, неплохо бы указывать что за компилятор и версия Qt, а также прикладывать к посту минимальный проект для тестирования.
Хорошо. Я учту на будущее. С запозданием скажу - gcc 4.6.1, Qt 5.0.1. Хмм... Надо бы компилятор апнуть, однако.
И, да, ваш код у меня не работает без приведения типа. А с приведением - всё ok. Поэтому - Vass, спасибо за ответ.

И ещё один момент, который я бы хотел у вас (alex312) спросить. В приведённом вами коде вы используете shared_ptr из std непосредственно. А у меня на подобное выдаётся ругань, и использовать данный умный указатель мне приходится из std::tr1. Вы случайно не знаете, почему так?

Конструктор shared_ptr без параметров разве не создает пустой указатель?
Я посмотрел варианты конструкторов shared_ptr и нашёл такой, который требует на вход nullptr. Отсюда я решил, что он-то точно инициализирует внутренний параметр им, а не чем то иным (а в случае с конструктором без параметров я подобной уверенностью не располагаю).


Название: Re: Инициализация shared_ptr нулевым указателем
Отправлено: alex312 от Апрель 10, 2013, 07:19
И ещё один момент, который я бы хотел у вас (alex312) спросить. В приведённом вами коде вы используете shared_ptr из std непосредственно. А у меня на подобное выдаётся ругань, и использовать данный умный указатель мне приходится из std::tr1. Вы случайно не знаете, почему так?
Для Qt5 *.pro файл добавить
Код:
CONFIG += c++11
Для Qt4, соответственно
Код:
QMAKE_CXXFLAGS += -std=c++0x


Название: Re: Инициализация shared_ptr нулевым указателем
Отправлено: mutineer от Апрель 10, 2013, 10:00
(а в случае с конструктором без параметров я подобной уверенностью не располагаю).

А какая тебе разница чем он там внутри инициализируется? На выходе ты получаешь невалидный указатель, как тебе и нужно


Название: Re: Инициализация shared_ptr нулевым указателем
Отправлено: m_ax от Апрель 10, 2013, 10:31
Нет никакой необходимости руками его инициализировать nullptr.. Он сам это сделает.


Название: Re: Инициализация shared_ptr нулевым указателем
Отправлено: fisenkdima от Апрель 11, 2013, 10:09
И ещё один момент, который я бы хотел у вас (alex312) спросить. В приведённом вами коде вы используете shared_ptr из std непосредственно. А у меня на подобное выдаётся ругань, и использовать данный умный указатель мне приходится из std::tr1. Вы случайно не знаете, почему так?
Для Qt5 *.pro файл добавить
Код:
CONFIG += c++11
Для Qt4, соответственно
Код:
QMAKE_CXXFLAGS += -std=c++0x
Уже было добавлено. Может быть подобная ошибка из за старой версии компилятора?

(а в случае с конструктором без параметров я подобной уверенностью не располагаю).

А какая тебе разница чем он там внутри инициализируется? На выходе ты получаешь невалидный указатель, как тебе и нужно
Проблема в том, что я не знал, что мы получим на выходе. Теперь знаю. Спасибо.


Название: Re: Инициализация shared_ptr нулевым указателем
Отправлено: alex312 от Апрель 11, 2013, 10:28
Уже было добавлено. Может быть подобная ошибка из за старой версии компилятора?
Скорее всего да.