2011-03-19 150 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