В конструкторе сначала инициализируется базовый класс, а затем все члены. Когда вы вызываете конструктор базового класса std::ostream
, вы передаете ему адрес mBuf
, который еще не был создан. Доступ к объекту, который еще не был создан, имеет неопределенное поведение.
Чтобы обойти это, вы можете изменить дизайн ваших классов следующим образом:
class AndroidLogStreamBuf : public std::streambuf
{
public:
AndroidLogStreamBuf() : std::streambuf()
{ }
~AndroidLogStreamBuf()
{ }
};
class AndroidLogOStream : public std::ostream
{
public:
AndroidLogOStream(AndroidLogStreamBuf *buf) :
std::ostream(buf),
mBuf(buf)
{ }
~AndroidLogOStream()
{ }
private:
AndroidLogStreamBuf *mBuf;
};
class AndroidLogOStreamWithBuf
{
private:
AndroidLogStreamBuf mBuf;
AndroidLogOStream mStream;
public:
AndroidLogOStreamWithBuf() :
mBuf(&mStream),
mStream()
{ }
virtual ~AndroidLogOStreamWithBuf()
{ }
AndroidLogOStream& getOStream()
{
return mStream;
}
};
Обратите внимание на порядок, который я объявил mBuf
и mStream
в AndroidLogOStreamWithBuf
: два поля будут инициализированы в этом порядке, независимо от того, в каком порядке они появляются в списке инициализатора конструктора. Кроме того, маркировка функций-членов как inline
в исходном коде была излишней: когда вы определяете функцию-член в определении класса, она автоматически помечается как встраиваемая.
Является ли это разумным проектом для вашей системы, зависит от того, как вы собираетесь использовать эти классы, но ответ, вероятно, "нет".