注:下面是我自己最近看书的总结,应该有错误
在C++中,如果子类与父类的函数名相同,那么子类将覆盖父类中同名的函数,也就是说,在继承关系中,方法签名只由方法名决定。若想实现多态效果,那么只能使用虚函数来实现。父类中的虚函数可能被编译为一个指针,编译子类时将子类相应的函数地址赋值给那个指针。
我想,继承在向上和向下两个方向起作用:
向上:子类可以使用父类中public和protected的方法和变量,实现代码重用。
向下:父类中的虚函数由不同的子类实现,实现多态。
在这个模型中,容易出问题的地方应该在“覆盖”上。子类对象赋值给父类变量后,执行的是父类中的函数,而不是自身的函数。这样一是容易使人陷入困惑,二是增大了对象的体积。所以我认为在设计时要尽量避免这种情况。如果是特意追求这种效果,一定要在注释中对此进行说明。
例如下面的代码:
#include <iostream>
using namespace std;
class Base
{
public:
virtual void f(float x){cout << "Base::f(float)" << x <<endl;}
void g(float x){cout << "Base::g(float)" << x <<endl;}
void h(float x){cout << "Base::h(float)" << x <<endl;}
};
class Derived:public Base
{
public:
void f(float x){cout << "Derived::f(float)" << x << endl;}
void g(int x){cout << "Derived::g(int)" << x << endl;}
void h(float x, float y){cout << "Derived::h(float, float)" << x << y <<endl;}
};
int main(void){
Derived d;
d.f(3.14);
d.g(3.14);
d.h(3.14);
return 0;
}
在编译时就会报错:
BaseDerived.cpp: In function ‘int main()’:
BaseDerived.cpp:26:10: error: no matching function for call to ‘Derived::h(double)’
BaseDerived.cpp:26:10: note: candidate is:
BaseDerived.cpp:16:8: note: void Derived::h(float, float)
BaseDerived.cpp:16:8: note: candidate expects 2 arguments, 1 provided
说明父类中的g(int)和h(float)被“覆盖”了。
这与Java中是不一样的,Java中只是函数名相同不会覆盖,而是实现了“重载”,例如:
class Base{
public void f(double x){System.out.println("Base.f(double):" + x);}
public void g(double x){System.out.println("Base.f(double):" + x);}
}
class Derived extends Base{
public void f(int x){System.out.println("Derived.f(int): " + x);}
public void g(double x, double y) {System.out.println("Derived.f(double, double): " + x + " " + y);}
}
class BaseDerived{
public static void main(String args[]){
Derived d = new Derived();
d.f(3.14);
d.g(3.14);
}
}
运行结果:
Base.f(double):3.14
Base.f(double):3.14
说明尽管子类中定义了同名的f(int)和g(double, double),但父类中的f(double)和g(double)仍能使用。