也来说说重载、覆盖和隐藏。(仔细分辨英文)

13 views
Skip to first unread message

邱戈川

unread,
Mar 1, 2006, 10:51:56 PM3/1/06
to 基于ACE和SpiderMonkey的SMS虚拟运营系统
以下部分借用C++高质量编程的话。

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

时代过客

unread,
Mar 2, 2006, 1:32:00 AM3/2/06
to 基于ACE和SpiderMonkey的SMS虚拟运营系统
判断函数是否相同是根据函数名和参数和返回值.然后根据不同的编译器厂商或特定标准对其managle后再生成raw
name,就这样成了全局唯一的一个函数

下面这两个函数的函数名和返回值相同,但参数则不一样.
众所周知,成员函数的参数列表中会由编译器在后台增加一个this的参数,因此第一个函数的this类型为
Parent* ,第二个函数this的类型为 const Parent*
,这两个是不同类型的,因此第二个函数并不是对第一个函数的override
void Fun();
void Fun const();

JackyYang

unread,
Mar 2, 2006, 11:22:42 AM3/2/06
to 基于ACE和SpiderMonkey的SMS虚拟运营系统
总结几点:
1。 virtual void Fun const(); 是笔误?应该是virtual void Fun()
const;
2。 时代过客 -
“判断函数是否相同是根据函数名和参数和返回值”的这个观点我不大赞同,函数的ID应该由函数名,参数类型/个数/位置决定,和返回值没关系。
3。 void Fun(); 和void Fun()
const我认为构成了重载。可以这样理解:Child继承了Parent,也就是Child内部有一个void
Fun()函数(假设ID是1001),同时Child自己定义了一个void
Fun()
const(假设ID是1002),这样满足了第一个条件“(1)相同的范围(在同一个类中);”。其他条件如时代过客所列。

candid Qiu

unread,
Mar 2, 2006, 7:48:32 PM3/2/06
to ACE...@googlegroups.com
答案:
首先不可能是重载,不是在同一个函数中。这是中国的翻译书的误导。

如果将A类改为 纯虚函数 virtual void Fun()=0;
然后试着编译就知道,不是覆盖,因为B类中实现了virtual void Fun() const; 后,如果实例化B会依然有错。

所以应改是隐藏!!

candid Qiu

unread,
Mar 2, 2006, 7:51:01 PM3/2/06
to ACE...@googlegroups.com
C++高质量编程编程中指的"在同一个类中",是指显式在同一个类中,继承关系使类中隐含有同父类的函数不算!!

时代过客

unread,
Mar 3, 2006, 12:17:30 AM3/3/06
to 基于ACE和SpiderMonkey的SMS虚拟运营系统
“判断函数是否相同是根据函数名和参数和返回值”的这个观点我不大赞同,函数的ID应该由函数名,参数类型/个数/位置决定,和返回值没关系。

==============================
有点印象,好像是我理解错了

邱戈川

unread,
Mar 3, 2006, 4:35:09 AM3/3/06
to 基于ACE和SpiderMonkey的SMS虚拟运营系统
今天和同事讨论后发现还有个新的有意思的现象:“虚构造函数”
不过这个需要新的编译器才支持,VC6还不行。

class A
{
public:
virtual A* Clone() = 0;
};

class B : public A
{
public:
virtual B* Clone();
};

这两个Clone函数是覆盖,尽管返回值不同。
但是注意:一定是子类指针和夫类指针的关系,如果是int
和 char 和 void等是不行的。

不知道如果是A&和B&或A和B这样是否可以,有兴趣可以试试。

JackyYang

unread,
Mar 3, 2006, 10:29:09 AM3/3/06
to 基于ACE和SpiderMonkey的SMS虚拟运营系统
查了资料,Candid是对的。
overload的函数需要在同一个类中。

邱戈川

unread,
Mar 5, 2006, 9:04:45 PM3/5/06
to 基于ACE和SpiderMonkey的SMS虚拟运营系统
对于“虚构造函数”:

virtual A* Clone() = 0; 和virtual B* Clone();
和覆盖,而且也可以定义返回值是A&或B&,但是不能是A或B。

在VC6中不支持,但是在.net 2003已经支持。

邱戈川

unread,
Mar 14, 2006, 4:08:43 AM3/14/06
to 基于ACE和SpiderMonkey的SMS虚拟运营系统
今天又来重复这个问题:
class A
{
public:
void Test(void);
void Test(void) const;

};

这个定义可以么?
是否是重载呢?
上面的解释有些问题,所以大家试试这个,可能有新发现。

Reply all
Reply to author
Forward
0 new messages