1. 重载(OverLoad)
成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
注解:要点是一定在一个类中,返回值不同或带有别的修饰符如const都没有用。有些中文翻译书里说在子类中"重载"虚函数说法是错误的!!
2. 覆盖(Override)
覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
注解:一定是子类和父类的关系且有virtual
,使用的是后无论定义指针类型是父类还是子类,只要new的时候用的是子类就一定调用的是子类的方法。换句话说:只要子类重新定义的这个虚函数,那么父类的对应函数已经不存在了。
子类的方法和父类的必须完全一致!!!
如:
class Parent
{
public:
virtual void Fun();
};
class Child : public Parent
{
public:
virtual void Fun();
};
Child *pCh = new Child();/*生成的是子类*/
Parent *pPd = pCh;
pPd->Fun();/*无论指针类型是什么,都是用子类的实现*/
3. 隐藏(Hidden)
除了重载和覆盖,剩下的同名函数都是隐藏,不用C++高质量编程讲的那么复杂,记住一点就可:具体调用那个方法,根据指针类型来判断。
如:
class Parent
{
public:
void Fun();
};
class Child : public Parent
{
public:
void Fun();
};
Child *pCh = new Child();
pPh->Fun();/*子类的方法*/
Parent *pPd = pCh;
pPd->Fun();/*父类的方法*/
思考:(我这两天遇到的问题),这个是什么?重载、覆盖还是隐藏?
class Parent
{
public:
virtual void Fun();
};
class Child : public Parent
{
public:
virtual void Fun const();
};
如果需要更详细的说明,建议看看
Thinking in C++,
Volume 1, 2nd Edition
Completed January 13, 2000
下面这两个函数的函数名和返回值相同,但参数则不一样.
众所周知,成员函数的参数列表中会由编译器在后台增加一个this的参数,因此第一个函数的this类型为
Parent* ,第二个函数this的类型为 const Parent*
,这两个是不同类型的,因此第二个函数并不是对第一个函数的override
void Fun();
void Fun const();
如果将A类改为 纯虚函数 virtual void Fun()=0;
然后试着编译就知道,不是覆盖,因为B类中实现了virtual void Fun() const; 后,如果实例化B会依然有错。
所以应改是隐藏!!
==============================
有点印象,好像是我理解错了
class A
{
public:
virtual A* Clone() = 0;
};
class B : public A
{
public:
virtual B* Clone();
};
这两个Clone函数是覆盖,尽管返回值不同。
但是注意:一定是子类指针和夫类指针的关系,如果是int
和 char 和 void等是不行的。
不知道如果是A&和B&或A和B这样是否可以,有兴趣可以试试。
virtual A* Clone() = 0; 和virtual B* Clone();
和覆盖,而且也可以定义返回值是A&或B&,但是不能是A或B。
在VC6中不支持,但是在.net 2003已经支持。
};
这个定义可以么?
是否是重载呢?
上面的解释有些问题,所以大家试试这个,可能有新发现。