重载
- 同一个类中的同名函数会重载;
- 重载函数的函数名相同,参数不同,不能用返回值判断是否是函数重载;
- 在不同类中的同名函数不是重载。
下面两函数为函数重载
void func()
{
std::cout << "调用了基类的func()" << std::endl;
}
void func(int a)
{
std::cout << "调用了基类的func(int)" << std::endl;
}
重写
- 重写发生在派生类和基类之间;
- 若派生类和基类有函数原型相同的成员函数,并用virtual关键字声明(基类成员函数用virtual关键字声明即可,而不管派生类成员函数是否用virtual关键字声明),则此成员函数为重写;
- 若派生类和基类有函数原型相同的成员函数,但没有用virtual关键字声明,则为重定义;
- 重写的派生类成员函数会覆盖与原型相同的基类成员函数。
重定义
- 重定义发生在派生类和基类之间;
- 若派生类和基类有函数原型相同的成员函数,但没有用virtual关键字声明,则派生类成员函数为重定义;
- 若派生类和基类有函数名相同但参数不同的成员函数,则派生类成员函数为重定义;
- 重定义的派生类成员函数会隐藏相应的基类成员函数。
下面派生类的func()成员函数为对基类func()成员函数的重写,而派生类的func()成员函数为对基类func(int)成员函数的重定义。所以派生类的func()成员函数会覆盖基类func()成员函数,派生类的func()成员函数会隐藏基类func(int)成员函数。
class Parent
{
public:
void func()
{
std::cout << "调用了基类的func()" << std::endl;
}
void func(int a)
{
std::cout << "调用了基类的func(int)" << std::endl;
}
};
class Child : public Parent
{
void func()
{
std::cout << "调用了派生类的func()" << std::endl;
}
void func1()
{
std::cout << "调用了派生类的func1()" << std::endl;
}
};
完整代码如下:
#include <iostream>
class Parent
{
public:
virtual void func()
{
std::cout << "调用了基类的func()" << std::endl;
}
void func(int a)
{
std::cout << "调用了基类的func(int)" << std::endl;
}
};
class Child : public Parent
{
public:
void func()
{
std::cout << "调用了派生类的func()" << std::endl;
}
void func1()
{
std::cout << "调用了派生类的func1()" << std::endl;
}
};
int main()
{
Child child1;
Parent * parent1 = &child1;//parent1指向child1的基类部分,所以只能调用其基
//类部分成员函数
parent1->func();//因为func()声明为虚函数,所以派生类func()会覆盖基类
//func(),故调用派生类func()
return 0;
}
程序执行结果如下:
若去掉基类func()成员函数前面的virtual,派生类func()会隐藏基类func(),但是派生类中的基类部分仍然有基类func()成员函数,只是对派生类对象隐藏了而已。所以若是通过指向派生类的基类指针调用func(),调用的应该是基类func(),结果如下:
覆盖和隐藏的区别
- 隐藏
#include <iostream>
class Parent
{
public:
virtual void func()//声明为虚函数
{
std::cout << "调用了基类的func()" << std::endl;
}
void func(int a)
{
std::cout << "调用了基类的func(int)" << std::endl;
}
};
class Child : public Parent
{
public:
void func()
{
std::cout << "调用了派生类的func()" << std::endl;
}
void func1()
{
std::cout << "调用了派生类的func1()" << std::endl;
}
};
int main()
{
Child child1;
child1.func();//func()声明为虚函数时,派生类func()会隐藏基类func()
//所以会调用派生类func()
child1.Parent::func();//因为基类func()只是被派生类func()隐藏了,
//而不是消失了,派生类仍然继承了基类的func(),
//所以可以显示地调用基类func()
return 0;
}
执行结果:
- 覆盖