一、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 *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 b; |
17 | b.print( "hello" ); //error,参数类型错误。此时调用的是print(int x)函数 |
18 | b.print(1); //right,此时基类同名函数被隐藏 |
19 | } |
在上列中,用子类对象b调用基类隐藏函数是可以实现的: b.A::print("hello"); 这样就可以突破隐藏的限制了。