虛擬函式為動態綁定(執行期決定),預設參數為靜態綁定(編譯期決定)。若基類別虛擬函式有預設參數,派生類別覆寫時不要重新定義預設參數,否則會出現「基類別預設參數配合派生類別函式本體」的異常行為。
/* test.cpp
* Created on: 2014.04.14
* Author: Spike
*/
#include <iostream>
#include <string>
using namespace std;
class Shape {
public:
enum ShapeColor { Red, Green, Blue };
virtual void draw(ShapeColor color = Red) const = 0;
};
class Rectangle : public Shape {
public:
virtual void draw(ShapeColor color = Green) const { // 錯誤:重新定義預設參數
cout << "Rectangle : ";
switch (color) {
case Red: cout << "Red"; break;
case Green: cout << "Green"; break;
case Blue: cout << "Blue"; break;
}
cout << endl;
}
};
class Circle : public Shape {
public:
virtual void draw(ShapeColor color) const { // 正確:不提供預設參數
cout << "Circle : ";
switch (color) {
case Red: cout << "Red"; break;
case Green: cout << "Green"; break;
case Blue: cout << "Blue"; break;
}
cout << endl;
}
};
int main() {
Rectangle R; Circle C;
R.draw(); // 靜態綁定:Green
Shape* pr = new Rectangle;
Shape* pc = new Circle;
pr->draw(Shape::Blue); // 動態綁定:Blue
pc->draw(Shape::Blue); // 動態綁定:Blue
pr->draw(); // 危險!靜態綁定用基類別預設 Red,動態綁定執行 Rectangle::draw(Red)
pc->draw(); // 正常:Circle 無預設參數,編譯錯誤(需傳參數)
return 0;
}
Rectangle : Red // 基類別預設參數 Red,但執行 Rectangle 版本