2014-12-14 2 views
2

Я только начинаю изучать C++, исходя из фона C#.Инициализация потока в конструкторе

Я создаю класс, который будет анализировать данные CSV, и я хочу, чтобы класс был инициализирован либо файловым путем, либо потоком. Если передан путь к файлу, _str_in должен быть установлен на вновь открытый ifstream.

Мой код ниже компилирует, но дает предупреждение о втором конструкторе. «Элемент ссылки инициализируется временным, который не сохраняется после выхода конструктора». Я предполагаю, что это предупреждение относится к следующему:

  1. ifstream создается и _str_in устанавливается для ссылки на него
  2. память назначен ifstream освобождается после того, как конструктор выходит
  3. _str_in теперь указывает на непредставленных выделенной памяти и может стать поврежденной.

Я пробовал разные способы выполнения этого и проверял многие вопросы, но я был в тупике — любые предложения?

class TokenParser 
{ 
    std::istream& _str_in; 
    char _delim; 

public: 
    TokenParser::TokenParser(std::istream& str_in, char delim) : _str_in(str_in), _delim(delim) 
    { 
    } 

    TokenParser::TokenParser(std::string& file_path, char delim) : _str_in(std::ifstream(file_path)), _delim(delim) 
    { 
    } 

ответ

2

Проблема заключается в том, что в значительной степени компилятор описывает: объект, созданный std::ifstream(file_path) пропадет к тому времени, конструктор завершает, поэтому ссылка _str_in мгновенно стала оборванной.

Вы можете обойти эту проблему, сделав std::ifstream объект внутри TokenParser, и использовать его, когда второй конструктор вызывается:

class TokenParser 
{ 
    std::ifstream _file; 
    std::istream& _str_in; 
    char _delim; 

public: 
    TokenParser::TokenParser(std::istream& str_in, char delim) : _str_in(str_in), _delim(delim) 
    { 
    } 

    TokenParser::TokenParser(std::string& file_path, char delim) : _file(file_path), _str_in(_file)), _delim(delim) 
    { 
    } 
... 
} 
0

Попробуйте это:
Использование универсальной ссылки и std::move в <algorithm>

class TokenParser 
{ 
std::istream&& _str_in; // notice the && 'universal reference' 
char _delim; 

public: 
TokenParser::TokenParser(std::istream&& str_in, char delim) 
: _str_in(std::move(str_in)), _delim(delim) 
{} 
// other ctors... 
} 
Смежные вопросы