c++ ifstream声明为public,但编译器说它是私有成员,不能被访问

C++ ifstream declared as public but compiler says its a private member that cant be accessed

本文关键字:成员 访问 不能 声明 ifstream public 编译器 c++      更新时间:2023-10-16

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;
    }
}

现在由于某种原因一旦我编译了我的main,里面只有

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

i get a error

C2248 - 'std::basic_ofstream<_Elem,_Traits>::basic_ofstream':无法访问在'std::basic_ofstream<_Elem,_Traits>'类中声明的私有成员

是否有一个解决方案,因为我尝试了这么多的方法来解决这个问题,但没有找到任何好的到目前为止。

谢谢

问题是在

这一行
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);

您的FileReader类包含ifstream数据成员,该成员具有已删除的复制构造函数。这将导致FileReader的复制构造函数也被隐式删除,因为编译器生成的复制构造函数将是错误的。

语句

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

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

FileReader my_file_reader("hello.txt");

现在你的代码将被编译。要编译原始语句,需要为FileReader定义一个move构造函数。

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

不妨也定义一个move赋值操作符

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

注意,在c++ 11兼容编译器的情况下,您实际上不需要为您的类定义move构造函数。要让编译器隐式地为您生成一个,只需去掉FileReader的析构函数,因为它无论如何都不会做任何有用的事情。然后,原始代码将在没有显式定义move构造函数的情况下编译。现场演示。

另一个选项是显式默认move构造函数和赋值操作符。

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

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