避免定義基類(base class)虛函數的預設參數, 如果基類虛函數包含預設參數, 衍生類別不要重新定義, 會產生異常;
虛函數(virtual)是動態綁定(dynamically bound),預設參數是靜態繫結(statically bound).
如果衍生類別(derived class)重新定義預設值, 執行個體化, 執行函數正常;
但在動態綁定時, 會出現,執行基類的預設參數, 卻是衍生類別的行為, 這樣的異常舉動.
talk is cheap, show you the code.
注意觀察動態綁定時, pr的輸出, 表現為基類的預設參數, 衍生類別的動作.
代碼:
/* * test.cpp * * Created on: 2014.04.14 * Author: Spike */ /*eclipse cdt, gcc 4.8.1*/ #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 { std::cout << "Rectangle : "; switch (color) { case Red : std::cout << "color = " << "Red" << std::endl; break; case Green : std::cout << "color = " << "Green" << std::endl; break; case Blue : std::cout << "color = " << "Blue" << std::endl; break; default: break; } } }; class Circle : public Shape { public: virtual void draw(ShapeColor color) const { std::cout << "Circle : "; switch (color) { case Red : std::cout << "color = " << "Red" << std::endl; break; case Green : std::cout << "color = " << "Green" << std::endl; break; case Blue : std::cout << "color = " << "Blue" << std::endl; break; default: break; } } }; int main() { Rectangle R; Circle C; R.draw(); //C.draw(); //報錯, 靜態繫結無法繼承參數 Shape* pr = new Rectangle; //動態綁定 Shape* pc = new Circle; pr->draw(Shape::Blue); pc->draw(Shape::Blue); pr->draw(); //靜態繫結, 使用基類的預設參數, 完成衍生類別的動作 pc->draw(); return 0; }
更多精彩內容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/cplus/
輸出:
Rectangle : color = Green Rectangle : color = Blue Circle : color = Blue Rectangle : color = Red Circle : color = Red
如果想使用基類虛函數的預設參數, 衍生類別不提供參數, 則需要使用NVI(non-virtual interface)的方法, 可以直接使用預設參數;
但是, 絕對不要重新定義一個繼承而來的預設參數值.
如, 以下代碼中, Rectangle的私人虛函數, doDraw()不要提供預設參數.
代碼:
/* * test.cpp * * Created on: 2014.04.14 * Author: Spike */ /*eclipse cdt, gcc 4.8.1*/ #include <iostream> #include <string> using namespace std; class Shape { public: enum ShapeColor {Red, Green, Blue}; void draw(ShapeColor color = Red) const { doDraw(color); } private: virtual void doDraw(ShapeColor color) const = 0; }; class Rectangle : public Shape { private: virtual void doDraw(ShapeColor color) const { std::cout << "Rectangle : "; switch (color) { case Red : std::cout << "color = " << "Red" << std::endl; break; case Green : std::cout << "color = " << "Green" << std::endl; break; case Blue : std::cout << "color = " << "Blue" << std::endl; break; default: break; } } }; int main() { Rectangle R; R.draw(); Shape* pr = new Rectangle; //動態綁定 pr->draw(Shape::Blue); pr->draw(); return 0; }
輸出:
Rectangle : color = Red Rectangle : color = Blue Rectangle : color = Red
作者:csdn部落格 Spike_King