对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>
有没有解决方案,我尝试了很多方法来解决这个问题,但到目前为止还没有找到任何好处。
由于
答案 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中修复。