указатель fstream не указывает - PullRequest
0 голосов
/ 22 января 2012

Я пытаюсь сделать указатель на fstream, чтобы я мог использовать его во всех моих методах класса:

class P
{
    private:
        fstream *fs;

    public:
        P()
        {
            fstream fs(filepath, openmode);
            this->fs = &fs;
        }
};

Но, похоже, он вообще не указывает на это, например, если я пишу:

fs->is_open() 

он вернет false, тогда как если я напишу:

fs.is_open()

, он вернет true.

Что вызывает это?Я также пытался изменить указатель на другой, например fstr, но это тоже не сработало.

Ответы [ 3 ]

4 голосов
/ 22 января 2012

Чтобы выполнить то, что вы просите, вам нужно использовать оператор new, например:

SmartIO::SmartIO(const char * filepath , Mode mode)
    : fs(NULL), buffer(NULL), offset(0)
{
    switch (mode)
    {
        case Mode::inText:
        {
            fs = new fstream(filepath,fstream::in|fstream::ate);
            break;
        }
        case Mode::inBinary:
        {
            fs = new fstream(filepath,fstream::in|fstream::binary|fstream::ate);
            break;
        }
    }

    if ((fs) && (fs->is_open()))
    {
        buffer = new std:vector<char>(fs->tellg(), 0);
        fs->seekg(0, ios::beg);
        fs->read(buffer->data(), buffer->size());
    }
    else
    {
        printf( "cant open the file!");
    }
}

SmartIO::~SmartIO()
{
    delete fs;
    delete buffer;
}
4 голосов
/ 22 января 2012

Вы указываете свой указатель на член fs на локально созданный объект fstream, который не существует, как только заканчивается его локальная область видимости. То, что у вас осталось, это висячий указатель.

Ваш this->fs теперь указывает на то, что не существует.

Всякий раз, когда вы используете этот висячий указатель для работы с потоком, это приводит к неопределенному поведению .

2 голосов
/ 22 января 2012

Вам необходимо динамически создать реальный объект потока.Примерно так может быть подход:

class Foo
{
    std::istream * p;
    bool must_clean;
public:
    Foo() : p(nullptr), must_clean(false)
    {
        if (...)      { p = new std::ifstream("somefile.txt"); must_clean = true; }
        else if (...) { p = new std::istringstream(global_buf); must_clean = true; }
        else          { p = &std::cin; }
    }
    ~Foo() { if (must_clean) delete p; }
    Foo(Foo const&) = delete;
    Foo & operator=(Foo const&) = delete);
};

Вы можете решить, хотите ли вы указатель istream, ostream или iostream.

...