C ++ ifstream声明为public,但编译器说它是一个无法访问的私有成员

时间:2014-07-16 19:41:45

标签: c++ inheritance ifstream

对C ++编程很陌生,所以对我来说很容易:)

我正在尝试使用C ++和设计模式为运动创建一个程序。 这是我现在使用的课程:

File.cpp-

 #include "File.h"
    #include <string.h>
    File::File() {}
    File::~File(void) {}

File.h -

    #pragma once

#include <string>
#include <iostream>

using namespace std;

class File
{
    public:
        //Ctor
        File();
        //Dtor
        ~File(void);

        //Opens up the file for streaming data I/O
        //virtual bool open();

    protected:      
        string _file_name;

};

FileReader.h

#pragma once
#include <fstream>

#include "File.h"

//Handles the input of our file
class FileReader : public File
{
    public:
        FileReader(string file_name_to_open);
        ~FileReader(void);

        bool isFileOpen();
        bool open();
        ifstream _in_stream;
};

FileReader.cpp

#include "FileReader.h"


FileReader::FileReader(string file_name_to_open) { 
    _file_name = file_name_to_open;
    open();
}

FileReader::~FileReader(void) { }

bool FileReader::isFileOpen() {
    return _in_stream.is_open();
}

bool FileReader::open() {
    if(isFileOpen()) {
        try{
            _in_stream.open(_file_name , ios::in);
        } catch(exception exce) {
            return false;
        }
        return true;
    } else {
        return false;
    }

}

现在由于某种原因,我编译了只有

的主
FileReader my_file_reader = FileReader("hello.txt");

我收到错误

  

C2248 - &#39; std :: basic_ofstream&lt; _Elem,_Traits&gt; :: basic_ofstream&#39;:无法访问在课程中声明的私有成员&#39; std :: basic_ofstream&lt; _Elem,_Traits&gt;&#39; < / p>

有没有解决方案,我尝试了很多方法来解决这个问题,但到目前为止还没有找到任何好处。

由于

2 个答案:

答案 0 :(得分:3)

问题在于行

FileReader my_file_reader = FileReader("hello.txt");

您尝试复制FileReader。由于FileReader的成员类型为ifstream,因此需要复制此成员。但它不能,因为ifstream s不可复制。 (来自编译器的错误消息可能会产生误导 - 它并不表示您无法复制,它表示复制构造函数是私有的。)

请更加注意C ++中的生命周期和对象复制。例如,而不是

FileReader(string file_name_to_open);

你应该使用

FileReader(const string& file_name_to_open);

答案 1 :(得分:1)

您的FileReader类包含ifstream数据成员,其成员deleted copy constructor。这会导致FileReader的复制构造函数也被隐式删除,因为编译器生成的复制构造函数会被错误地删除。

声明

FileReader my_file_reader = FileReader("hello.txt");

你使用复制初始化,这需要一个可访问的复制/移动构造函数,因此错误。最简单的解决方法是使用直接初始化:

FileReader my_file_reader("hello.txt");

现在你的代码将编译。要获取要编译的原始语句,您需要为FileReader定义移动构造函数。

    FileReader(FileReader&& other)
    : _in_stream(std::move(other._in_stream))
    {}

也可以定义一个移动赋值运算符

    FileReader& operator=(FileReader&& other)
    {
        _in_stream = std::move(other._in_stream);
        return *this;
    }

请注意,对于符合C ++ 11的编译器,您实际上不需要为类定义移动构造函数。要让编译器为您隐式生成一个,只需删除FileReader的析构函数,它无论如何都没有做任何有用的事情。然后你的原始代码将编译而没有明确定义的移动构造函数。 Live demo

另一种选择是显式默认移动构造函数和赋值运算符。

FileReader(FileReader&&) = default;
FileReader& operator=(FileReader&&) = default;

也会产生正确的行为。不幸的是,这些都不是VS2013的选项。我相信这将在下一版本的VisualStudio中修复。