Effective C++ 37絕不重新定義繼承而來的缺省參數值
記得之前有同事吐槽過Java中居然沒有缺省參數這個東西,想要達到缺省參數的目的只能靠蹩腳的函數重載。但今天發現了C++中缺省參數的坑。
C++中的virtual函數是動態綁定的,而缺省值卻是靜態綁定的。
舉例來說:
class Shape{
public:
virturl void draw(Color c = red ) const = 0;
}
class Circle : public Shape{
public:
virturl void draw(Color c = green ) const;
}
Sharp* ps;
Sharp* pc = new Circle;
pc的靜態類型是Sharp,而動態類型為Circle.
由於動態綁定技術,pc 可以通過虛表找到自己的虛函數,而c++因效率原因而讓缺省值靜態綁定,所以當pc調用draw時的默認參數是red,這一定是一個非常難以發現的BUG
如果讓他們都有相同的默認參數,則又代碼重復,比較好的解決方式是:
class Shape{
public:
void draw(Color c = red ) const{
ondraw(c);
}
private:
virtual void draw(Color c) const;
}
class Circle : public Shape{
private:
virtual void draw(Color c) const;
};
所以,我們唯一應該覆寫的東西是virtual函數,所以應該把靜態綁定的東西(缺省參數)定義在non-virtual函數中。
Effective C++ 37絕不重新定義繼承而來的缺省參數值