1、函数的覆盖
例子:
class animal
{
……
virtual void breathe()
{
cout<<”animal breathe”<<endl;
}
};
class fish: public animal
{
Public:
void breathe()
{
cout<<”fish breathe”<<endl;
}
};
无论函数名,还是参数列表都是一样的,这成为函数的覆盖(overrode)。
构成函数覆盖的条件为:
(1)基类函数必须为虚函数(使用virtual关键字进行声明)
(2)发生覆盖的两个函数要分别位于派生类和基类中。
(3)函数名称与参数列表必须完全相同。
覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
2、函数的隐藏
成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
3、函数的隐藏
例子:
class animal
{
Public:
……
void breathe()
{
cout<<”animal breathe”<<endl;
}
};
class fish: public animal
{
Public:
void breathe()
{
cout<<”fish breathe”<<endl;
}
};
所谓隐藏,是指派生类中具有与基类同名的函数(不考虑参数列表是否相同),从而在派生类中隐藏了基类的同名函数。
4、引用
引用就是一个变量的别名,它需要用另一个变量或对象来初始化自身。
int a=5;
int &b=a;//用&表示声明了一个引用b,并用变量a进行初始化。
引用和用来初始化引用的变量指向的是同一块内存,因此通过引用或变量可以改变同一块内存中的内容。
例子:
引用只是一个别名,是一个变量或对象的替换名称。引用的地址没有任何意义,因此C++没有提供访问引用本身地址的方法。引用的地址就是它所引用的变量或对象的地址,对引用的地址所做的操作就是对被引用的变量或对象的地址所作的操作。指针是地址,指针变量要存储地址值,因此要占用存储空间,我们可以随时修改指针变量所保存的地址值,从而指向其它内存。
5、::
::作用域标示符。这种以”::”开始的方法表明该函数是一个全局函数。
例子:
BOOL CWnd :: UpdateWindow()
{
return ::UpdateWindow(m_hWnd);
}
读者在定义自己的成员函数时,如果调用的API函数名与自己的函数名不同,那么该API函数名前可以加也可以不加”::”符号,编译器会自动识别API函数。但是如果当前定义的成员函数与内部调用的API函数名相同,那么后者前面必须加”::”符号,否则程序在编译或运行时就会出错。
5、
return不能直接返回多个值,如果你想通过函数内部返回多个值的话,一般有三种方法:
第一种:返回结构体
#include <stdio.h>
//定义一个结构体
typedef struct _a
{
int a;
int b;
}A,*PA;
//函数返回结构体变量,它里面就可以包含多个值
PA func()
{
PA a = new A();
a->a = 2;
a->b = 3;
return a;
}
int main()
{
PA test = func();
printf("%d %d/n", test->a, test->b);
delete test;
return 0;
}
第二种:以引用方式传递函数参数
#include <stdio.h>
//要以引用方式传递参数,否则,在函数内部改变形式参数的值,
//函数返回之后,参数值依然不变
void func(int& a, int& b)
{
a = 2;
b = 3;
}
int main()
{
int a = 0;
int b = 0;
func(a, b);
printf("%d %d/n", a, b);
return 0;
}
第三种:以类型指针方式传递函数参数
#include <stdio.h>
void func(int* a, int* b)
{
*a = 2;
*b = 3;
}
int main()
{
int a = 0;
int b = 0;
func(&a, &b);
printf("%d %d/n", a, b);
return 0;
}