2014-05-05 116 views
1

經常討論無法轉發聲明std :: string和std :: wstring的問題。據我瞭解,原因是這些類型typedefing模板類basic_string的實例化的:正向聲明std :: string和std :: wstring

namespace std { 
    typedef basic_string<char> string; 
    typedef basic_string<wchar_t> wstring; 
} 

又向前推進了的typedef的聲明不是由語言允許的。使用繼承,而不是類型定義

那豈不是爲C++更好的標準:

namespace std { 
    class string : public basic_string<char> {}; 
    class wstring : public basic_string<wchar_t> {}; 
} 

所以這樣我們可以向前聲明的std :: string和std :: wstring的?

+4

你爲什麼需要提前申報? '#include '照顧任何聲明就好了。 – JAB

+0

這就是我想要避免的 - '#include ' – chook

+1

你爲什麼要避免'#include'?還有其他方法可以提高編譯速度;看看預編譯頭文件。作爲一個經驗法則, –

回答

5

豈不是C++標準使用繼承,而不是更好的typedef [...]

性病:: basic_string的並不意味着任何被繼承形成。這個限制允許實現一個std :: basic_string,因爲它沒有虛函數表,所以它更便宜(更快)來創建和銷燬。

如果你需要定義std :: [w]字符串,只需要#include吧。

編輯(應答評論)

一個C++(和標準庫)的指導原則是「不支付你不使用什麼」。這意味着代碼以這種方式編寫,您不應該爲不需要的功能導致運行時成本。

如果每個實例都有一個虛擬表(這將使std :: string,在性能關鍵的代碼中被禁止),創建一個std :: string實例會更加昂貴。

相反,std :: string的目的是作爲C char*機制的快速,類型安全的RAII實現。同樣,你不應該嘗試繼承std :: vector,list,map,shared_ptr,unique_ptr等等。

如果您確實需要字符串基類,請考慮自己編寫your_namespace::[w]string_base(一個簡單的實現將在內部封裝std::[w]string)。

+2

只有在定義了至少一個虛擬函數的情況下才存在虛函數表 – chook

+0

這是正確的,但是因爲在繼承的情況下需要虛擬析構函數(以避免進入UB),允許繼承一個'std :: basic_string ',實際上這意味着至少'用虛擬析構函數定義類'。 – utnapistim

+0

> std :: basic_string並不意味着以任何形式繼承。 你能給一個參考或解釋嗎?不是「因爲」 – chook

相關問題