C++开发中级
959 浏览 5 years, 10 months
6.3 重写方法时的特殊情况
版权声明: 转载请注明出处 http://www.codingsoho.com/重写方法时的特殊情况
当重写方法时,需要注意几种特殊情况。 本节将列出您可能遇到的一些情况。
1.静态超类方法
在C++中,无法重写静态方法。对于多数情况而言,知道这一点就足够了。然而,在此您需要了解一些推论。
首先,方法不可能既是静态的又是虚的。出于这个原因,试图重写一个静态方法得到的结果并非您的预期。如果子类中存在的静态方法与超类中的静态方法同名,实际上这是两个独立的方法。
下面的代码显示了两个类,这两个类刚好都具有一个名为beStatic()的静态方法。这两个方法毫无关系。
class SuperStatic{
public:
static void beStatic(){
cout << "SuperStatic being static." << endl;
}
};
class SubStatic{
public:
static void beStatic(){
cout << "SubStatic keepin' it static." << endl;
}
};
由于静态方法属于类,调用两个类的同名方法时将调用各自的方法。
SuperStatic::beStatic();
SubStatic::beStatic();
输出为:
SuperStatic being static.
SubStatic keepin' it static.
当用类访问这些方法的时候一切都很正常。当涉及到对象时,这一行为就不是那么明显。在C++中,可以使用对象调用静态方法,但由于方法是静态的因此没有this指针,也无法访问对象本身,因此使用对象调用静态方法等价于使用classname::method()调用静态方法。回到前面的示例,您可以编写如下的代码,但是结果令人惊讶:
SubStatic mySubStatic;
SuperStatic & ref = mySubStatic;
mySubStatic.beStatic();
ref.beStatic();
beStatic()的第一次调用显然调用SubStatic版本,因为调用它的对象显式地声明为SubStatic。第二个调用的运行方式可能并非您预期的那样。这个对象是一个SuperStatic引用,但指向的是一个SubStatic对象。在此情况下,会调用SuperStatic版本的beStatic()。原因是当调用静态方法时,C++不关心对象实际上是什么,只关心编译时类型。在此情况下,该类型为SuperStatic的引用。
有的编译器会阻止这种赋值,错误如下
[Error] invalid initialization of reference of type 'SuperStatic&' from expression of type 'SubStatic'
前面示例的输出如下:
SubStatic keepin' it static.
SuperStatic being static.
静态方法属于定义它的类名称,而不属于特定的对象。当类中的方法调用静态方法时,所调用的版本是通过正常的名称解析来决定的。当使用对象调用时,对象实际上并不涉及调用,只是用来判断类型。
参考代码 SubOverrideMethodStatic.cpp
2.超类方法被重载
当指定名称以及一组参数重写某个方法时,编译器隐式地隐藏超类中的同名方法的所有其他实例。其想法为:如果您重写了给定名称的某个方法,可能是想重写所有的同名方法,您只是忘记这么做了,因此应该作为错误处理。这是有意义的,您可以这么考虑——为什么您想要修改方法的某些版本而不修改其他版本呢?考虑下面的子类,这个子类重写了一个方法而没有重写相关的重载方法: