2011-03-30 160 views
3

可能需要超載下標運算符的場景是什麼?運算符超載[]

什麼是assert函數與此有關?我在大多數情況下看到使用assert的下標重載,需要對此進行解釋。

回答

7

您可能會在自定義容器上重載[]運算符,以提供訪問元素的語法/語義更清晰的方式。

例如my_container[3] = 9;my_container.set(3, 9);

當然更爲清楚,你可以重載[]做任何實質上,但你可能不應該。例如,您可以使my_object[3]my_object增加3,但在語義上012r運算符會傳送按索引查找,並且最好讓您的接口符合預期。

您可以使用assert進行快速和骯髒的邊界檢查;它會導致你的程序混亂死亡,這總是比引入細微的內存損壞更好。好處是,assert是一個可以從生產代碼編譯出來的宏,這意味着您可以支付邊界檢查開銷的開銷,而不是在生產中檢查您的容器,而無需修改代碼。

1

好吧,我對這方面的知識有限,我可以說,在這些類中有一系列元素時。 Vector/String例如。爲了聲明你可能想看看這個網站。 --LINK--

0

您可能想要更改索引的範圍(例如,從1而不是從0開始編制索引),還是用一維數組表示高維數組?

3

你可能會考慮重載operator[]的類操作(索引(通過單個字段有意義,因爲它是矢量(按位置索引)集或映射(按鍵索引)的情況)注意,如果存在多個維度,通過該指數,它可能是有意義的使用不同的運營商(operator()),爲operator[]需要一個參數。你或許應該閱讀Operator Overloading的C++ FAQ精簡版條目。

一般assertoperator[](或任何其他操作員)無關assert是一種在運行時確定操作的某些先決條件已滿足的方法,應該用於快速失敗當您檢測到某些不變量已損壞時,將難以通過

+1

只是一個說明,但如果有多個維度,傳統的解決方案是返回一個代理,它也重載[]。人們可以爭論這兩種方法,但代理解決方案確實提供了與C風格數組陣列相同的語法,即c [i] [j]。 – 2011-03-30 16:13:51

+0

@James Kanze:就是說,在大多數情況下不是最好的主意。從鏈接的C++ FAQ中閱讀[13.10](http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.10)和以下幾點。 – 2011-03-31 10:16:48

+0

@David Rodriguez常見問題表達了一位作者的意見。關於這個問題的意見 不同。 (在FAQ中的幾個陳述,特別是那些關於性能的陳述,都是錯誤的。一個 解決方案很容易映射到另一個,因此性能永遠不會成爲 比另一個更喜歡的原因。)我更喜歡使用( )我---我的 受到巴頓和納克曼的影響---但兩種選擇都是有效的, 值得一提,從我工作的地方來看, [] []選項似乎更受歡迎,並被認爲是更「經典」的解決方案。 – 2011-03-31 10:56:11

1

斷言絕對沒有做與索引操作符operator[]本身

Assert用於檢查調試版本中的先決條件/不變式,因此在投入生產之前會對其進行違規。爲什麼你似乎更往往比其他地方有注意到他們

索引運營商傾向於index out of range類型的情況下,這可能解釋。我在每個參數化函數中至少使用一次assert,並且每個類使用幾次(檢查不變量)。

HTH

1

如果要實現一個類,它是一個集合或集合的包裝你可能超載operator[]。對我而言,如果操作可以在常量或接近常量的時間執行,那麼我只會重載operator[],因爲這是數組索引執行的方式。使用它來查找散列表中的值可能是有意義的,但不能將其索引到鏈接列表中。

如果您發現在operator[]的實現中使用asserts,則很可能強制索引參數在集合的範圍內。這,國際海事組織,是不正確使用assert,因爲assert應該用來捕捉內部編程錯誤,而不是你的程序被稱爲錯誤的方式。最終用戶或客戶端應用程序不應該看到斷言錯誤。另一種可能性是這個類只在內部使用,在這種情況下,斷言錯誤會顯示內部編程錯誤,而不是客戶端傳入的錯誤參數。

+0

好的提及時間限制;這就是阻止操作員在許多STL容器上發生的原因。雖然他們允許在「地圖」的情況下記錄時間。 – 2011-03-30 16:42:55