2016-05-18 60 views
1

我有以下錯誤:如何讓一個類的多個對象與一個std :: mutex?

filesystem.hpp:11:7: error: use of deleted function ‘std::mutex& std::mutex::operator=(const std::mutex&)’ 
In file included from /usr/include/c++/6.1.1/mutex:44:0, 
       from includes.hpp:11, 
       from htmlparser.hpp:4, 
       from htmlparser.cpp:1: 
/usr/include/c++/6.1.1/bits/std_mutex.h:98:12: note: declared here 
    mutex& operator=(const mutex&) = delete; 
      ^~~~~~~~ 

...哪些已經有一些問題要問(如this onethat one)。基於這些我想下面的類代碼:

class Filesystem { 
    private: 
     std::string dir = getCurrentPath(); 
     mutable std::mutex fsMut; 
    public: 
     Filesystem() {} 
     ~Filesystem() {} 
     Filesystem(const Filesystem&) : fsMut() { } 

     //Few more functions 
}; 

...這可悲的是不工作(或者甚至改變錯誤)。

現在我的代碼與前面提到的問題有什麼不同:我在private部分的兩個類中聲明Filesystem fs;。然而,在我看來,這將是完全正確的,而對於一個類別,它會傳遞給另一個類別,這個錯誤將被返回(以及錯誤如何隱含地刪除該類別和Filesystem)。
所以我沒有複製或移動類afaik,但是那會出什麼問題呢?我怎樣才能改變我的代碼,使其工作?

編輯:
完整的錯誤:

htmlparser.cpp: In member function ‘strSet Htmlparser::parseLinks(std::__cxx11::string, std::__cxx11::string, std::__cxx11::string)’: 
htmlparser.cpp:10:39: error: use of deleted function ‘Robotsparser& Robotsparser::operator=(const Robotsparser&)’ 
    rsmap[origUrl] = Robotsparser(origUrl); 
            ^
In file included from htmlparser.hpp:5:0, 
       from htmlparser.cpp:1: 
robotsparser.hpp:7:7: note: ‘Robotsparser& Robotsparser::operator=(const Robotsparser&)’ is implicitly deleted because the default definition would be ill-formed: 
class Robotsparser { 
     ^~~~~~~~~~~~ 
robotsparser.hpp:7:7: error: use of deleted function ‘Filesystem& Filesystem::operator=(const Filesystem&)’ 
In file included from robotsparser.hpp:5:0, 
       from htmlparser.hpp:5, 
       from htmlparser.cpp:1: 
filesystem.hpp:11:7: note: ‘Filesystem& Filesystem::operator=(const Filesystem&)’ is implicitly deleted because the default definition would be ill-formed: 
class Filesystem { 
     ^~~~~~~~~~ 
filesystem.hpp:11:7: error: use of deleted function ‘std::mutex& std::mutex::operator=(const std::mutex&)’ 
In file included from /usr/include/c++/6.1.1/mutex:44:0, 
       from includes.hpp:11, 
       from htmlparser.hpp:4, 
       from htmlparser.cpp:1: 
/usr/include/c++/6.1.1/bits/std_mutex.h:98:12: note: declared here 
    mutex& operator=(const mutex&) = delete; 
      ^~~~~~~~ 

而其他類:A

class Robotsparser { 
    private: 
     std::string url; 
     Filesystem fs; 
    public: 
     Robotsparser(std::string u) : url(u) {} 
     ~Robotsparser() {} 
}; 

class A { 
    private: 
     std::mutex crawlMut; 
     Filesystem fs; 
    public: 
     A(std::string); 
}; 

類早在Makefile編譯,這或許可以解釋爲什麼它給出了錯誤的Robotsparser類。

+0

這是複製(和分配)的問題,而不是創建多個實例。當複製發生時,你想要複製的關係是什麼?他們可以分別獲得他們自己無關的互斥鎖,或者可以使用'shared_ptr '讓所有副本共享一個互斥鎖。 –

+0

它真的很容易複製一個沒有意義的對象。常用的方法是調用一個函數,該函數根據值獲取對象,將對象填充到像'vector','map'或'list'這樣的容器中,然後複製包含對象的對象。無論如何,無法通過強制拷貝FileSystem的簡化版來複制。您可能需要編輯您的問題和[提供偉大而光榮的MCVE。](http://stackoverflow.com/help/mcve) – user4581301

+0

我沒有看到如何複製發生在這裏,這是我的問題的特定部分。除此之外,我想共享互斥可能會很好。我如何實現? –

回答

2

錯誤意味着有一個賦值操作試圖某處發生......

在你Filesystem類,編譯器並沒有抱怨的拷貝構造函數:

Filesystem(const Filesystem&) : fsMut() {} //because there is no copying of fsMut here 

但,編譯器會爲您生成一個複製賦值運算符,因爲您沒有定義它。並且在編譯器生成一個,它調用每個成員的複製賦值運算符。

我認爲你的意圖是:你應該定義所有的複製/移動賦值運算符(和構造函數),並確保你不要複製/移動任何實例擁有的互斥體。

Filesystem(const Filesystem& f2) 
{ 
     std::lock_guard<std::mutex> lk2(f2.fsMut); 
     /*do your stuff but do not copy f2.fsMut*/ 
} 

Filesystem(Filesystem&& f2) 
{ 
     std::lock_guard<std::mutex> lk2(f2.fsMut); 
     /*do your stuff but do not move f2.fsMut*/ 
} 

Filesystem& operator = (const Filesystem&) 
{ 
    std::lock(this->fsMut, f2.fsMut); 
    std::lock_guard<std::mutex> lk1(this->fsMut, std::adopt_lock); 
    std::lock_guard<std::mutex> lk2(f2.fsMut, std::adopt_lock); 

     //do your stuff but do not copy fsMut 
     return *this; 
} 

Filesystem& operator = (Filesystem&& f2) 
{ 
    std::lock(this->fsMut, f2.fsMut); 
    std::lock_guard<std::mutex> lk1(this->fsMut, std::adopt_lock); 
    std::lock_guard<std::mutex> lk2(f2.fsMut, std::adopt_lock); 

     //do your stuff but do not move fsMut 
     return *this; 
} 

完全說明這裏:http://coliru.stacked-crooked.com/a/75d03fd564f8b570 另外,考慮使用,lock_guard「兩個互斥S和std::lock鎖定在複製/移動賦值運算符兩個互斥。

雖然我仍然有我對你的意圖保留,我看到了一個成員聲明,​​如:

mutable std::mutex fsMut; 

採用mutable是從const成員函數修改成員;這裏它通常用於鎖定/解鎖const成員函數中的互斥鎖。

0

錯誤的第一位表示什麼?

htmlparser.cpp: In member function ‘strSet Htmlparser::parseLinks(std::__cxx11::string, std::__cxx11::string, std::__cxx11::string)’: 
htmlparser.cpp:10:39: error: use of deleted function ‘Robotsparser& Robotsparser::operator=(const Robotsparser&)’ 
    rsmap[origUrl] = Robotsparser(origUrl); 

它說,在Htmlparser::parseLinks,在這條線

rsmap[origUrl] = Robotsparser(origUrl); 

您使用的是不存在的拷貝賦值運算符。

原因,它不存在是編譯器沒有產生它適合你,因爲它不能,因爲你的類的mutex成員是不可拷貝。

但是,你真正的問題是爲什麼編譯器試圖首先使用此:

So I am not copying or moving the class afaik

但你可以看到,就行了編譯器報價,轉讓。你沒有顯示什麼rsmap是,但看着運營商[]爲std::map顯示它默認構造一個元素,返回一個對新值的引用,然後你的代碼複製 - 分配給它。 std::unordered_map也是如此。

如果您的課程不可複製或分配,您不能這樣做 - 您需要構建適當的對象。該emplace方法做到這一點,給人的代碼是這樣的:

rsmap.emplace(origUrl, origUrl); 

或者,你可以保持你現有的代碼和寫複製/移動構造函數和賦值運算符。

相關問題