5. 显式调用父类的成员函数
在有继承关系的类中,一旦子类对父类同一个成员函数进行了覆盖,则子类对象以默认调用的一定是子类的成员函数,而父类的成员函数则被覆盖(屏蔽)。如果再子类成员函数中需要显示调用父类的成员函数,则需要使用类名和作用域限定符(::)来显式的调用被覆盖的成员函数。
语法
class 子类名: public 父类名 {
返回类型 成员函数名(形式参数列表) {
// 调用父类的成员函数(用父类名指定名字空间)
父类名::成员函数名(实际调用参数列表)
}
};
示例
// filename: call_demo.cpp
#include <iostream>
#define PI (3.1415926)
// 点类(描述一个点的位置,面积等信息)
class Point {
public:
Point(float ax=0, float ay=0):x(ax), y(ay) {
std::cout << "Point(" << x << "," << y << ")\n";
}
void info(void) {
std::cout << "点(" << x << "," << y << ")\n";
}
void moveTo(float new_x, float new_y) {
x = new_x; y = new_y;
}
float getArea(void) {
return 0;
}
protected:
float x;
float y;
};
// 圆类(描述圆的位置、半径、面积等信息)
class Circle : public Point {
public:
Circle(float ax, float ay, float radius)
: Point(ax, ay), r(radius) {
// x = ax; y = ay; r = radius;
std::cout << "Circle(" << x << "," << y << "," << r << ")\n";
}
void info(void) {
std::cout << "圆(" << x << "," << y << "," << r << ")\n";
}
void showBaseInfo(void) {
// 显式调用Point类的info 而非自己的info函数
Point::info();
}
float getArea(void) {
return PI*r*r;
}
protected:
float r; // 半径
};
int main(int argc, char * argv[]) {
Point p1(3, 5);
Circle c1(4, 6, 10);
c1.info();
p1.info();
p1.moveTo(100, 105);
// 子类对象不存在moveTo,则调用父类的方法
c1.moveTo(200, 210);
p1.info();
c1.info();
c1.showBaseInfo();
std::cout << "程序结束!" << std::endl;
return 0;
}
编译和运行结果如下
weimz@mzstudio:~$ g++ -o call_demo call_demo.cpp
weimz@mzstudio:~$ ./call_demo
Point(3,5)
Point(4,6)
Circle(4,6,10)
圆(4,6,10)
点(3,5)
点(100,105)
圆(200,210,10)
点(200,210)
程序结束!
从上述结果可以看出 c1.showBaseInfo(); 实际打印的是 点(200,210),此成员函数调用的是 Point::info 成员函数。
实验
自己写一个显式调用被覆盖的父类成员函数的示例。