重载(overload):在C++程序中,可以将语义、功能相似的几个函数用同一个名字表示,但是函数参数不同,即构成函数重载。
(1)相同的范围(在同一个类或域中)
(2)函数名称相同
(3)函数参数不同(参数类型、参数个数、参数顺序)
(4)不考虑返回类型
(5)不考虑virtual关键字
重写(又叫覆盖,override):派生类函数覆盖基类函数。
(1)不同的范围(在同一种类中(父子类))
(2)函数名称相同
(3)函数参数相同(参数类型、参数个数、参数顺序)
(4)返回类型相同
(5)基类必须有virtual关键字
注:重写基类虚函数的时候,会自动转换这个函数为virtual函数,不管有没有加virtual,因此重写的时候不加virtual也是可以的,不过为了易读性,还是加上比较好。
重定义(又叫隐藏,redefining):派生类的函数屏蔽了与其同名的基类函数。
(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; }
};
void main()
{
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
}
例二:
class Base
{
private:
virtual void display(){ cout<< "Base display()" << endl; }
void say(){ cout << "Base say()" << endl; }
public:
void exec(){ display(); say(); }
void f1(string a){ cout << "Base f1(string)" << endl; }
void f1(int a){ cout << "Base f1(int)" << endl; }//overload重载,两个函数在Base类内部被重载
};
class DerivedA:public Base
{
public:
void display(){ cout << "DerivedA display()" << endl; }//override重写,基类中display为虚函数,故此处为重写
void f1(int a, int b){ cout << "DerivedA f1(int, int)" << endl; }//redefining重定义,f1函数在Base类中不为虚函数,故此处为重定义
void say(){ cout << "DerivedA say()" << endl; }//redefining重定义,同上
};
class DerivedB:public Base
{
public:
void f1(int a){ cout << "DerivedB f1(int)" << endl; }//redefining重定义
};
void main()
{
DerivedA a;
Base *b = &a;
b->exec();//display():version of DerivedA called(polymorphism) //DerivedA display()
//say():version of Base called(always) //Base say()
a.exec();//same result as last statement //DerivedA display()
//Base say()
cout<<endl;
a.say();//DerivedA say()
cout<<endl;
//a.f1(1);//error:no matching function, hidden!
cout<<endl;
DerivedB c;
c.f1(1);//version of DerivedB called //DerivedB f1(int)
}
例三:
class A
{
public:
virtual void print(void)
{
cout<<"A::print()"<<endl;
}
//friend void print(A a){a.print();}
};
class B:public A
{
public:
virtual void print(void)
{
cout<<"B::print()"<<endl;
}
};
class C:public B
{
public:
virtual void print(void)
{
cout<<"C::print()"<<endl;
}
};
void print(A a)
{
a.print();
}
void main()
{
A a, *pa,*pb,*pc;
B b;
C c;
pa=&a;
pb=&b;
pc=&c;
a.print();
b.print();
c.print();
pa->print();
pb->print();
pc->print();
print(a);
print(b);
print(c);
}