重载:如派生类与基类有同名函数,但参数列表不同,但派生类与基类间同名函数不会发生重载,因为不在同一作用域。
隐藏:派生类成员与基类成员同名,则派生类会隐藏基类的同名成员,使得基类中与派生类同名的成员在派生类中无法被访问。
隐藏只与成员名有关,与参数列表、返回值类型无关。隐藏是静态绑定,即在编译时就确定了调用的函数或变量。
覆盖:派生类中某个函数的函数名、返回值类型、参数列表与基类中某个虚函数相同,则派生类中的该函数与基类中的虚函数为覆盖关系,使得使用基类指针或引用调用该函数时,会根据运行时的实际对象来选择调用基类或派生类的函数。覆盖只能发生在虚函数之间。覆盖是动态绑定,即在运行时才确定调用的函数,实现了多态。
class Base {
public:
Base(int ma = 0, int mb = 0) :
b_ma(ma), b_mb(mb) {}
/**************************************************/
void func() {
cout << "Base::func()" << endl;
}
void func(int a) { // 重载
cout << "Base::func(int a)" << endl;
}
void func01() {
cout << "Base::func01()" << endl;
}
/**************************************************/
virtual void show() {
cout << "Base::show()" << endl;
}
/**************************************************/
int b_ma;
int a = 3;
private:
int b_mb;
};
class Derive :public Base {
public:
Derive(int b_ma = 1, int b_mb = 1, int ma = 1):
Base(b_ma,b_mb), d_ma(ma) { }
/**************************************************/
void func() {
cout << "Derive::func()" << endl;
}
/**************************************************/
virtual void show() {
cout << "Derive::show()" << endl;
}
int a = 4;
private:
int d_ma;
};
void test() {
Derive d;
cout << d.a << endl; // 4。 发生隐藏,访问派生类的a
cout << d.Base::a << endl; // 3。 需要访问基类的a,则需要加作用域
d.func(); // Derive::func()。 发生隐藏,访问派生类的func()
d.func01(); // Base::func01()。 调用基类的func01()
d.Base::func(); // Base::func()。 需要访问基类的func(),则需要加作用域
// d.func(3); 出错,无法发生重载,因为不在同一作用域
d.Base::show(); // Base::show()。
/**************************************************/
Base b01;
Derive d01;
b01 = d01; // 基类对象 = 派生类对象 可行
// d01 = b01; 派生类对象 = 基类对象 不可行
Base* bptr = &d01; // 基类指针可指向派生类对象
bptr->func(); // Base::func()。 但只能访问基类的成员。 func()非虚函数,则为静态绑定。
((Derive*)bptr)->func(); // Derive::func()。 转成派生类指针类型,则可访问派生类的成员。
// Derive* dptr = &b01; 派生类的指针不可指向基类对象
}