一、C++重载
即在同一个类中声明相同的函数名,但形参列表的参数类型与及参数的数目不同时,应会发生重载。包括函数重载和运算符重载。看个例子:
01 |
class A{
|
02 |
03 |
public :
|
04 |
05 |
void fun(){};
|
06 |
07 |
void fun( int a){};
|
08 |
09 |
void fun( int a, int b){};
|
10 |
11 |
void fun( double b){};
|
12 |
13 |
}; |
二、C++重写
即基类中声明为virual的函数,子类继承相应的virtual函数,但实现了自己的方法。我们就称为重写(也称覆盖)。子类调用同名的函数时,需判断调用的是子类从基类重写的函数,还是在基类的函数的实现。重写是C++多态性产生的机制,把基类中带有virual关键字的函数,在子类中实现自己的版本。这叫重写。注意与隐藏的区别之处。例子:
01 |
class A{
|
02 |
03 |
public :
|
04 |
05 |
void foo(){
|
06 |
07 |
cout<< "A.foo()" <<endl;
|
08 |
09 |
}; |
10 |
11 |
virtual void fun()
|
12 |
13 |
{ |
14 |
15 |
cout<< "A()" <<endl;
|
16 |
17 |
} |
18 |
19 |
}; |
20 |
21 |
class B: public A{
|
22 |
23 |
public :
|
24 |
25 |
void foo() //此时子类的foo实现会隐藏父类的foo实现
|
26 |
27 |
{ |
28 |
29 |
cout<< "B.foo()" <<endll;
|
30 |
31 |
} |
32 |
33 |
void fun() //实现基类的虚函数fun()
|
34 |
35 |
{ |
36 |
37 |
cout<< "B()" <<endl;
|
38 |
39 |
} |
40 |
41 |
}; |
42 |
43 |
int main()
|
44 |
45 |
{ |
46 |
47 |
A new A();
|
48 |
49 |
a new B();
|
50 |
51 |
a->fun(); //多态性的体现,此时基类对象a将调用子类的fun函数
|
52 |
53 |
a->foo(); //调用基类的foo();
|
54 |
55 |
return 0;
|
56 |
57 |
} |
三、C++隐藏:
对基类中不存在virual关键字的函数,子类继承后,如果再次定义一个同名函数(此时注意不是重载),不管定义的同名函数形参列表类型及个数是否相同,基类的同名函数彻底被隐藏(其实还是可以用子类对象调用基类隐藏函数的,见下面)。此时调用子类对象中的函数时,就只能调用子类中定义的函数(注意此函数并不继承自基类的同名函数,并不是所谓的重写)。例子:
01 |
class A{
|
02 |
public :
|
03 |
void print(string s){
|
04 |
cout<< "A print()" <<endl;
|
05 |
}
|
06 |
}; |
07 |
08 |
class B : public A{
|
09 |
public :
|
10 |
11 |
void print( int x){ //此时会发生隐藏,没有重载
|
12 |
cout<< "B print(int a)" <<endl;
|
13 |
}
|
14 |
}; |
15 |
int main(){
|
16 |
B |
17 |
b.print( "hello" ); //error,参数类型错误。此时调用的是print(int x)函数
|
18 |
b.print(1); //right,此时基类同名函数被隐藏
|
19 |
} |
在上列中,用子类对象b调用基类隐藏函数是可以实现的: b.A::print("hello"); 这样就可以突破隐藏的限制了。