2013-04-08 85 views
0

參考Well, how does the custom deleter of std::unique_ptr work?的std ::的unique_ptr定製刪除

構造

std::unique_ptr<ErrorHandling> error_; 

RecursiveDescentParser::RecursiveDescentParser(std::string inputStream, bool fileService, 
      boost::optional<std::string> filePathName, std::ofstream &writer){ 

    if (fileService == true){ 
     error_(new ErrorHandling(fileService, writer)); <---- compiler error 
    } 
    else{ 
     error_(new ErrorHandling(fileService, std::ofstream())); <---- compiler error 
    }  
} 

編譯錯誤

Error 1 error C2247: 'std::default_delete<_Ty>::operator()' not accessible because 'std::unique_ptr<_Ty>' uses 'private' to inherit from 'std::_Unique_ptr_base<_Ty,_Dx,_Empty_deleter>' 

錯誤原因描述here

我決定自'std::default_delete<_Ty>::operator()private,因爲(在這種情況下std::unique_ptr)子類已指定private inheritance,我會寫我自己的定製刪除。問題是我對語法和符號的成功感到不舒服。

+1

「ErrorHandling'聲明'private'的析構函數? – 2013-04-08 16:15:41

+0

我實際上沒有聲明析構函數(合成)並正式聲明瞭一個,但編譯器錯誤依然存在。 – Mushy 2013-04-08 17:09:42

回答

5

此行

error_(new ErrorHandling(fileService, writer)); 

是因爲unique_ptr沒有一個operator()錯誤。錯誤信息有點誤導,因爲它的基類似乎有一個(但幸運的是私有)。

你可能打算

error_.reset(new ErrorHandling(fileService, writer)); 

這使得unique_ptr擁有一個新的對象。

+0

即使沒有初始對象,調用reset來初始化std :: unique_ptr也是安全的嗎? – Mushy 2013-04-08 17:15:54

+0

是的,您使用的默認構造函數將初始指針設置爲null。用真正的指針代替它是完全可以的。 – 2013-04-08 17:18:38

+0

非常有趣,謝謝。 – Mushy 2013-04-08 17:19:21

4

問題是,您正嘗試在unique_ptr上使用函數調用操作符,這不是一個有效的操作。然後會造成一些混淆,因爲您的特定實現碰巧有一個不可訪問的操作符,而不是根本沒有操作符,從而給出一個奇怪的錯誤消息。

我假設你實際上是試圖重新error_給自己一個新的指針:

error_.reset(new ErrorHandling(fileService, writer)); 
// ^^^^^^ 

UPDATE:如果你想定製刪除(其中,重申一下,你在這種情況下沒有) ,它可能看起來像:

struct ErrorHandlingDeleter 
{ 
    void operator()(ErrorHandling * p) {/* do something to release the pointer */} 
}; 

std::unique_ptr<ErrorHandling, ErrorHandlingDeleter> error; 
+0

我正在嘗試以下語法'std :: unique_ptr error_(new ErrorHandling(fileService,writer));'但收到編譯錯誤進行我認爲需要定義我自己的自定義刪除程序。儘管利用'reset'是解決方案,我可以請看一個SSCCE定製刪除器的例子嗎? – Mushy 2013-04-08 17:18:38

+0

@Mushy:這是聲明和初始化一個新的唯一指針的語法。但是,你不想這樣做;你想修改一個現有的,爲此你需要調用'reset'。 'error_(some_pointer)'做了一些完全不同的事情 - 它試圖像函數那樣調用唯一的指針,這是不可能的。 – 2013-04-08 17:21:17

+0

@Mushy:對於定製刪除器的示例,Google指出我可以訪問http://stackoverflow.com/questions/8274451和其他許多地方。但是,當然,您不需要在這裏定製刪除器;他們只是在'刪除'不是正確的事情。 – 2013-04-08 17:23:05

相關問題