函数重载:
同一类中,函数参数不同(类型,顺序不同),返回值可同可不同,virtual关键字可有可无。
void Func(int x,int y);
void Func(double x,double y);
该函数被c编译器编译后库中名字为_Func,c++编译器编译后 产生
_Func_int_int,_Func_double_double标识符,以便程序调用相应函数。
如果C++程序要调用已经被编译后的C函数,该怎么办?
解答:假设某个C函数的声明如下:
void foo(int x, int y);
该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int
之类的名字用来支持函数重载和类型安全连接。由于编译后的名字不同,C++程序不能直接调用C函数。C++提供了一个C连接交换指定符号extern“C”来解决这个问题。
例如:
extern “C”
{
void foo(int x, int y);
…// 其它函数
}
这就告诉C++编译译器,函数foo 是个C连接,应该到库中找名字_foo而不是找
_foo_int_int。C++提供了C连接交换指定符号extern“C”来解决名字匹配问题。
覆盖
(派生类函数覆盖基类函数):
1. 不同范围(分别位于派生类与基类函数);
2. 函数名字相同
3. 参数相同
4. 基类函数必须有virtual关键字
class Base
{
public:
void f(int x){ cout << "Base::f(int) " << x << endl; }
void f(float x){ cout << "Base::f(float) " << x << endl; }
virtual void g(void){ cout << "Base::g(void)" << endl; }
};
class Derived : public Base
{
public:
virtual void g(void){ cout << "Derived::g(void)" << endl; }
};
void Test()
{
Derived d;
Base *pb = &d;
pb->f(42); // Base::f(int) 42
pb->f(3.14f); // Base::f(float) 3.14
pb->g(); // Derived::g(void)
}
隐藏
(派生类屏蔽了与其同名的基类函数):
1. 若派生类函数与基类函数同名,参数不同,无论有无virtual关键字,基类函数被隐藏。
2. 若派生类函数与基类函数同名,参数相同,基类函数无virtual关键字,基类函数被隐藏。
class Base
{
public:
virtual void f(float x){ cout << "Base::f(float) " << x << endl; }
void g(float x){ cout << "Base::g(float) " << x << endl; }
void h(float x){ cout << "Base::h(float) " << x << endl; }
};
class Derived : public Base
{
public:
virtual void f(float x){ cout << "Derived::f(float) " << x << endl; }
void g(int x){ cout << "Derived::g(int) " << x << endl; }
void h(float x){ cout << "Derived::h(float) " << x << endl; }
};
//(1)函数Derived::f(float)覆盖了Base::f(float)。
//(2)函数Derived::g(int)隐藏了Base::g(float),而不是重载。
//(3)函数Derived::h(float)隐藏了Base::h(float),而不是覆盖。
void Test()
{
Derived d;
Base *pb = &d;
Derived *pd = &d;
// Good : behavior depends solely on type of the object
pb->f(3.14f); // Derived::f(float) 3.14
pd->f(3.14f); // Derived::f(float) 3.14
// Bad : behavior depends on type of the pointer
pb->g(3.14f); // Base::g(float) 3.14
pd->g(3.14f); // Derived::g(int) 3 (surprise!)
// Bad : behavior depends on type of the pointer
pb->h(3.14f); // Base::h(float) 3.14 (surprise!)
pd->h(3.14f); // Derived::h(float) 3.14
}
注意:
1. 基类的构造函数,析构函数,赋值函数不能被派生类继承。
2. 派生类的构造函数应在初始化列表内调用基类的构造函数;
3. 基类与派生类的析构函数加vitrual关键字
4. 在编写派生类赋值函数时,不要忘记对基类的数据成员重新赋值
继承
(提高程序的复用性):
若A是基类,B是派生类,则B继承A的数据与函数。
class A
{
public:
void Func1(void);
void Func2(void);
};
class B :public A
{
public:
void Func3(void);
void Func4(void);
};
void Test()
{
B b;
b.Func1();//继承
b.Func2();//继承
b.Func3();
b.Func4();
}