2011-03-19 121 views
2

尝试执行以下操作时出现这些错误。 我有一个FileMgr类来处理一个输入和输出文件与两个成员函数将输入的每一行复制到列表中,并写入列表的每个成员的输出。注意:以下功能在由我的主人直接处理时可以正常工作!所以不要费心去试图弄清楚我在使用复制函数做什么,我花了很多时间弄清楚它们,现在它们工作正常,问题不在那里。奇怪的iostream编译错误

FileMgr::FileMgr(string inFilename, string outFilename) 
{ 
    input.open(inFilename); 
    output.open(outFilename); 
} 

bool FileMgr::writeFileToList(list<string> &l) 
{ 
    // copy each line of file into new member of list<string> 
    if(!input.is_open()) 
     return false; 

    copy(istream_iterator<string>(input), istream_iterator<string>(), back_inserter(l)); 

    return true; 
} 

bool FileMgr::writeListToFile(list<string>::iterator begin, list<string>::iterator end) 
{ 
    // copy each member of list<string> in output file, beginning and ending at iterators begin, end 
    // note that I have to pass a "false" end iterator, that is, end--, for it to work 
    if(!output.is_open()) 
     return false; 

    copy(begin, end, ostream_iterator<string>(output, "\n")); 

    return true; 
} 

和到这里一切都很好。然后我的其他类,后者从FileMgr列表,它应该让用户编辑它(我不在那儿,因为这些错误还),所以我的继承人声明的一部分:

class Dictionary 
{ 
public: 
    Dictionary(string inFileName = "dictionary.txt", string outFileName = "output.txt"); 
    void userEditor(); 
//private: 
    list<string> dictionary; 
    FileMgr manager; 
    bool findWord(string word); 
    bool addWord(string word); 
    bool deleteWord(string word); 
    void sortAndFix(); 
    void saveAndExit(); 

,这里是我的定义到目前为止,这基本上只是在构造函数:

Dictionary::Dictionary(string inFileName, string outFileName) 
{ 
    // open files and copy to list; sort and fix list. 
    manager = FileMgr(inFileName, outFileName); 

    dictionary.push_back(" "); 
    if(manager.writeFileToList(dictionary)) 
     cout << "File successfully read from " << inFileName << endl; 
    else 
     cout << "Error in reading " << inFileName << endl; 

    sortAndFix(); 
} 

当我编译,我得到的只是显示这些错误在构造函数中的某处未知(因为它在文件中的唯一代码,我从编译时这些错误):

1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\istream(860): error 

C2249: 'std::basic_ios<_Elem,_Traits>::operator =' : no accessible path to private member declared in virtual base 'std::basic_ios<_Elem,_Traits>' 
1>   with 
1>   [ 
1>    _Elem=char, 
1>    _Traits=std::char_traits<char> 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 10.0\vc\include\ios(177) : see declaration of 'std::basic_ios<_Elem,_Traits>::operator =' 
1>   with 
1>   [ 
1>    _Elem=char, 
1>    _Traits=std::char_traits<char> 
1>   ] 
1>   This diagnostic occurred in the compiler generated function 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator =(const std::basic_istream<_Elem,_Traits> &)' 
1>   with 
1>   [ 
1>    _Elem=char, 
1>    _Traits=std::char_traits<char> 
1>   ] 
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\ostream(604): error C2249: 'std::basic_ios<_Elem,_Traits>::operator =' : no accessible path to private member declared in virtual base 'std::basic_ios<_Elem,_Traits>' 
1>   with 
1>   [ 
1>    _Elem=char, 
1>    _Traits=std::char_traits<char> 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 10.0\vc\include\ios(177) : see declaration of 'std::basic_ios<_Elem,_Traits>::operator =' 
1>   with 
1>   [ 
1>    _Elem=char, 
1>    _Traits=std::char_traits<char> 
1>   ] 
1>   This diagnostic occurred in the compiler generated function 'std::basic_ostream<_Elem,_Traits> &std::basic_ostream<_Elem,_Traits>::operator =(const std::basic_ostream<_Elem,_Traits> &)' 
1>   with 
1>   [ 
1>    _Elem=char, 
1>    _Traits=std::char_traits<char> 
1>   ] 

我不明白什么是错的。我的FileMgr工作正常,当从我的主测试时,为什么编译器会像这样从另一个类的FileMgr工作?

+0

编辑为清晰。 – Edoz 2011-03-19 07:11:39

+1

您的错误消息表明您正在对输入变量进行错误操作,因此您可能也想要发布该代码。另请参阅下面的答案。如果我最终对此正确,您的问题可能需要一个新的标题:) – phooji 2011-03-19 08:40:18

+0

找出哪一行会导致最后两个错误,因为这些错误似乎与您的'writeFileToList'函数无关。 – rve 2011-03-19 09:14:43

回答

2

我相信,你的问题是在这条线:

manager = FileMgr(inFileName, outFileName); 

从你的代码FileMgr似乎FileMgr有一个stre作为数据成员,我是input。当您执行上述行时,您将调用FileMgr的赋值运算符,默认情况下,它将尝试一次一个地复制所有数据成员。但是,流的复制功能不可访问(它们被标记为private并且未实现)。你得到的错误几乎肯定是由于C++编译器注意到它需要复制流,但是由于复制函数无法访问而失败。

要改变这种情况,尝试在构造函数的成员初始化列表初始化manager

Dictionary::Dictionary(string inFileName, string outFileName) 
    : manager(inFileName, outFileName) { 
    /* ... */ 
} 

这将初始化manager具有给定参数,而不是试图分配manager对象与正确的参数。

希望这会有所帮助!

+0

就是你说的做FileMgr管理器(inFileName,outFileName)的一样;在构造函数里面? ?因为显然这编译,但我想我不能申报经理两次(因为我在类的声明已经宣布它为什么可以在此编译在一切都不是它就像一个INT;在申报;然后在构造你的INT A = 3;?但不是一个已定义,这就是为什么我在做它的其他方式,但感谢,似乎工作(但我想知道为什么:)) – Edoz 2011-03-19 20:50:09

+0

这是* *相似于这样做,但他们有完全不同的行为。初始化列表用于在构造函数开始运行之前构造数据成员。它会像构建'FileMgr管理器(inFileName,outFileName)'一样构造'manager'。但是,如果你只是写出'FileMgr管理器(inFileName,outFileName)',编译器会将它解释为创建一个没有连接到数据成员的局部变量。一般来说,您会希望使用初始化程序列表来设置复杂的数据成员,而不是在构造函数中为它们赋值。 – templatetypedef 2011-03-19 20:52:41

+0

哦,好的。我不知道初始化列表,我认为这只是一个捷径。仍然,编译器如何让我声明一个具有相同名称和类型的成员变量的局部变量?我认为这是不可能的 – Edoz 2011-03-19 20:53:46

1
bool FileMgr::writeFileToList(list<string> &l); 

FileMgr::writeFileToList通过参考接收list<string>类型的参数。

所以,你应该真正做到 -

list<string> dictionary; 
if(manager.writeFileToList(&dictionary)) 
          ^error. You should not use & symbol here. 

参数类型不list<string>*l发送地址。

+0

是的,这是我的问题的第2部分。当我这样做时,我会得到这两个错误! – Edoz 2011-03-19 07:17:22

+0

'copy(...);'的第三个参数是做什么的? (即'inserter(l,l.end())')。你也发送一个大小为** 0 **的列表。 – Mahesh 2011-03-19 07:24:39

+0

我现在正在使用back_inserter(l),正如nawaz所建议的那样。即时复制输入到l,但我仍然得到该错误 – Edoz 2011-03-19 07:27:44

1

只要写:不需要

if(manager.writeFileToList(dictionary)); 

&。事实上,这会导致错误!

顺便说一句,您的std::copy写错了。这是正确的:

copy(istream_iterator<string>(input), istream_iterator<string>(), std::back_inserter(l)); 

请注意最后一个参数。这是std::back_inserter(l)

+0

是的,这是我的问题的第2部分。当我这样做时,我会得到这两个错误! – Edoz 2011-03-19 07:17:04

+0

@Edoz:更新了我的答案! – Nawaz 2011-03-19 07:24:01

+0

好吧,是的,这是更清洁的方式,但我仍然得到这两个错误 – Edoz 2011-03-19 07:29:00

0

if(manager.writeFileToList(&dictionary))应改为

if(manager.writeFileToList(dictionary))

注意你不能转换Type*Type&

+0

是的,这是我的问题的第2部分。当我这样做时,我会得到这两个错误! – Edoz 2011-03-19 07:16:19