2009-11-12 19 views
2

假設我有一個類Animal繼承自Animal類, 您可能需要在Dog :: operator =中插入對​​Animal :: operator =的調用。在C++中調用母類運算符的常用方法?

什麼是最可讀/常用的寫法?

我想我知道那兩個......

static_cast<Animal*>(this)->operator=(other); 

this->Animal::operator=(other); 
+2

在第二種情況下,'this->'是多餘的; 'Animal :: operator =(other);'就夠了。 – 2009-11-12 14:48:37

+2

此外,第一個案例可以看起來更「自然」,因爲'* static_cast (this)= other;' – 2009-11-12 14:50:39

回答

12

因爲你是從一個子類方法

Animal::operator=(other); 

無需this->內這樣做。範圍解析語法完全符合要求。我沒有看到與演員「間接」做這件事的意義。

還請注意,在一般情況下使用強制轉換進行轉換可能不會產生預期結果,因爲它不會禁用虛擬方法調用的動態分辨率。 (而且,BTW,賦值運算符可以被聲明爲虛擬的)。這樣做的一個明顯後果是,使用虛擬方法時,「投射」變體可能會導致無限遞歸。

+2

事實上,如果你在派生類中覆蓋它,它可能*應該是虛擬的:你幾乎肯定會在某個時候得到不想要的行爲。 – moswald 2009-11-12 15:22:07

+0

@mos:通常,當有人在談論「賦值運算符」時,它們表示複製賦值運算符。複製指派操作符在層次結構中不會互相覆蓋,因爲它們的簽名不同於類到類(不同的參數類型)。因此,您的推理不適用於複製分配操作員。它可能不適用於任何賦值運算符,因爲它是一個具有自己規則的特殊成員函數。 – AnT 2009-11-12 15:26:00

+0

@mos:...但是在一般情況下,即使有賦值操作符,也存在危險。 – AnT 2009-11-12 15:26:51

6

this->Animal::operator=(other);是正確的方法,你完全有資格指你的父母實現方法,你不需要爲此拋棄自己,並使代碼更難閱讀。

+0

Alexandrescu也會使用:'Animal&me = * this;我=其他;'。我不確定我是否明白了這一點的確切目的,但它是乾淨的,並且產生(據我所知)同樣的效果。 – 2009-11-12 15:09:01

+1

正如@AndreyT所說,你有操作符=虛擬的危險,除了沒有調用你想要的方法之外,你可以以無限遞歸結束。 – 2009-11-12 15:11:58

+1

......除了這個「Alexandrescu」變體在虛擬分配操作符的情況下也可能導致無限遞歸。是的,我知道虛擬分配操作符不是人們經常看到的東西(如果有的話),而是作爲一種通用方法(即不是僅指定操作員),這會嚴重破壞。 – AnT 2009-11-12 15:15:15