2013-10-28 55 views
0

我的問題是關於從std庫中包裝一些容器或對象,以及這樣做的成本。 假設我需要創建ThreadSafeStack類。我會包裝std::stack容器並使用互斥體使其線程安全。這將是完全可以的,因爲新的ThreadSafeStack的功能值得花費(函數調用)。但是如果我想在調試時將std::mutex包裝到類MyMutex中以添加日誌記錄功能呢?在你看來,這是否值得?從std包裝C++功能,有時是一個壞主意?

如果我只是爲了方便而做這樣的事情,爲避免在我的所有文件中寫入std::using::std?你認爲這很愚蠢嗎?

我已經讀了一些關於函數調用的內容(例如this),我會說這不會是一個很大的開銷。

+3

你的包裝函數調用最有可能會在適當的優化級別被內聯,從而導致* ZERO *開銷。例如,檢查[this case](http://stackoverflow.com/a/15964113/1762344):包含在'operator *'中的指針解引用導致相同的彙編代碼與原始指針解引用相同。優化過程中可以蒸發很多級別的C++抽象。 –

+1

我還補充說,如果你在做IO(例如寫入日誌文件),那麼函數調用是你最擔心的問題。 – selalerer

+0

你說得對@selalerer。 – Athanase

回答

2

這將是完全可以的,因爲新的ThreadSafeStack的功能將是值得的成本(函數調用)。

您的封裝函數調用很可能會被內聯到適當的優化級別上,導致ZERO開銷。例如,檢查this case:將指針取消引用包裝到operator*中會得到與原始指針取消引用相同的彙編代碼。在優化過程中,很多級別的C++抽象可以被蒸發。

雖然,虛擬函數調用不太可能被內聯。所以,只要有意義,就使用正常的函數。

但是如果我想在調試時將std :: mutex包裝到類MyMutex中以添加日誌記錄功能呢?

記錄可能會增加一些顯著的成本,但如果你只在調試過程中需要它 - 在釋放通過ifdef S或通過任何其他方式構建,比如你可以安全地將其禁用:

const bool do_logging = false; // somewhere 
// ... 
if(do_logging) // branching can be easily removed by optimizer, 
       // because do_logging is constant 
    // ... 
else 
    // ... 

在你看來,這是否值得?

是的,當然。建立基於標準圖書館設施的更有用的抽象是常見的做法。

如果我只是爲了方便而做這樣的事情,避免在我的所有文件中編寫std ::或using :: std會怎樣?你認爲這很愚蠢嗎?

這取決於您的項目 - 在某些情況下,甚至可以在頭文件中使用using namespace std。但是請注意 - 將包含此標頭的人可能會遇到姓名衝突。

在大多數情況下,可以在.cpp文件的頭部使用using namespace std(在inlucde之後)。但是,即使這是不能接受的,你可以隨時使用using指令在功能層面:

void foo() 
{ 
    using namespace std; 
    // ... 
} 
相關問題