2013-06-24 3 views
1

первый участник, но я считаю, что я правильно проверил прошлые сообщения и не нашел решение, которое работает. Я использую Visual Studio 2012 ...C++ std :: ofstream класс

По существу, все, что я хочу сделать, - это вывод потока в файл журнала, принадлежащий объекту. У меня нет зависаний о том, как именно это должно быть достигнуто, но ничего в архивах не работает.

Как я понимаю, это принято решение должно работать:

#include <fstream> 
// classA.h 
class A { 
private: 
    std::ofstream * _logfile; 
public: 
    A(void); 
    void dosomething(void) const; 
} 

и

// classA.cpp 
#include classA.h 
A::A(void) : _logfile(0) { 
    std::ofstream output("logfile.txt",std::ofstream::app); 
    _logfile = &output; 
} 

A::dosomething(void) { 
    *_logfile << "Print something" << std::endl; 
} 

и

// main.cpp 
int main() { 
A a = new A(); 
a->dosomething(); 
} 

компилируется нормально, но просто зависает. Скорее всего, я думаю, потому что выход исчезает на конце ctor. Каков хороший надежный способ достижения этой функциональности? Другие предложения StackOverflow чтения приводить к ошибкам компилятора ...

Спасибо, Крис

+2

'A a = new A();'? Я не верю вам, когда вы говорите, что этот код компилируется. –

+0

Да, извините, пропуская * и это не единственная ошибка ... – loadsamates

ответ

2

код имеет неопределенное поведение как _logfile является dangling pointer после того, как A была построен потому, что оно принимает адрес output который является локальным переменным, определенным в конструкторе A: когда конструктор A «ы завершается, output разрушается. _logfile затем разыменовывается в do_something(), что является неопределенным поведением и является вероятной причиной зависания.

Чтобы решить, просто использовать std::ofstream член и сделать A без копируемого (как потоки не копируемые, но подвижны):

class A { 
private: 
    std::ofstream _logfile; 
    A(const A&); 
    A& operator=(const A&); 
public: 
    A() : _logfile("logfile.txt",std::ofstream::app) {} 
    void dosomething() 
    { 
     _logfile << "Print something" << std::endl; 
    } 
}; 
+0

Большое вам спасибо, hmjd, это работает наконец. Честно говоря, я не понимаю (причину) необходимости сделать A не скопированным. Вы можете указать мне на объяснение? – loadsamates

+0

@loadsamates, если класс имеет не скопируемый элемент, то содержащийся класс также не копируется. – hmjd

1

В конструкторе, вы настраиваете _logfile в адрес локального ofstream объекта. Когда конструктор возвращается, этот объект уничтожается. _logfile остается как висячий указатель, а ваши операции над ним в функции dosomething приводят к неопределенному поведению. Почему бы вам просто не объявить _logfile как обычный объект ofstream, а не указатель?

2

У вас есть указатель на объект в стеке, он будет будут удалены после того, как конструктор закончил:

#include classA.h 
A::A(void) : _logfile(0) { 
    std::ofstream output("logfile.txt",std::ofstream::app);//it's on the stack 
    _logfile = &output;//pointer to an object on the stack 
} 

A::dosomething(void) { 
    *_logfile << "Print something" << std::endl; 
} 

лучше использовать:

std::ofstream _logfile; 

и запустите его в списке инициализации конструктора:

A::A(void) : _logfile("logfile.txt",std::ofstream::app){}