您的位置:首页 > 编程语言 > C语言/C++

C++ - 虚函数(virtual function)缺省参数的异常表现 及 正确使用方法

2014-04-14 15:20 591 查看

虚函数(virtual function)缺省参数的异常表现 及 正确使用方法

本文地址: http://blog.csdn.net/caroline_wendy/article/details/23679691

避免定义基类(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;
}

输出:

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


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐