目录
概念定义
函数重载:必须在同一类中进行,且子类无法重载父类的函数,父类同名函数将被名称覆盖不会发生重载,重载是在编译期间根据参数类型和个数决定函数调用的。
函数重写:必须发生于父类与子类之间,并且,父类与子类中的函数必须有完全相同的原型,使用virtual声明之后能够产生多态(如果不使用virtual,那叫重定义),多态是在运行期间根据具体对象的类型决定函数调用的。
案例分析
本篇对重写、重载、重定义三个概念进行举例和辨析,先上案例,定义一个父类:
class Parent
{
//这个三个函数都是重载关系
public:
void abc()
{
printf("abc");
}
virtual void func()
{
cout<<"func() do..."<<endl;
}
virtual void func(int i)
{
cout<<"func() do..."<<i<<endl;
}
virtual void func(int i, int j)
{
cout<<"func() do..."<<i<< " "<<j<<endl;
}
virtual void func(int i, int j, int m , int n)
{
cout<<"func() do..."<<i<< " "<<j<<endl;
}
protected:
private:
};
在这个类中,同名的func函数出现了四次,每次func函数所对应的输入参数都不一样,均在一个类中,这就是函数重载。 那么接着再定义一个子类:
class Child : public Parent
{
public:
void abc()
{
printf("child abc");
}
/*
void abc(int a)
{
printf("child abc");
}
*/
virtual void func(int i, int j)
{
cout<<"func(int i, int j) do..."<<i<< " "<<j<<endl;
}
virtual void func(int i, int j, int k)
{
cout<<"func(int i, int j) do.."<< endl;
}
protected:
private:
};
同理,在这个子类里面,又有两个func函数,那定义在子类中的两个函数func,是函数重载的关系。
那么现在的func函数就拢共有5个了,它们之间各自是什么关系呢?先画一个示意图:
那么,可以看成,父类中的"virtual void func(int i, int j)"和子类中的"virtual void func(int i, int j)",这两个函数不是在同一个类里面,而且函数原型完全一样,而且,它们加了"virtua"关键字,那么这俩函数的关系就是重写。如果还是以上条件,只是没有加"virtual"关键字,那么它俩的关系就是重定义了!
务必强调,必须是函数原型完全一样才行,就是说不仅函数名称要一样,而且函数的输入参数的变量名和数量也必须完全一致才可以。
再往下看,在主调函数中定义一个由子类创建的对象c1:
//重载重写和重定义
void main()
{
//: error C2661: “Child::func”: 没有重载函数接受 0 个参数
Child c1;
//c1.func();
//子类无法重载父类的函数,父类同名函数将被名称覆盖
c1.Parent::func();
//1 C++编译器 看到func名字 ,因子类中func名字已经存在了(名称覆盖).所以c++编译器不会去找父类的4个参数的func函数
//2 c++编译器只会在子类中,查找func函数,找到了两个func,一个是2个参数的,一个是3个参数的.
//3 C++编译器开始报错..... error C2661: “Child::func”: 没有重载函数接受 4 个参数
//4 若想调用父类的func,只能加上父类的域名..这样去调用..
c1.func(1, 3, 4, 5);
//c1.func();
//func函数的名字,在子类中发生了名称覆盖;子类的函数的名字,占用了父类的函数的名字的位置
//因为子类中已经有了func名字的重载形式。。。。
//编译器开始在子类中找func函数。。。。但是没有0个参数的func函数
cout<<"hello..."<<endl;
system("pause");
return ;
}
如果想通过像在父类中那样重载的方式,来在子类中重载父类的函数,是不可能的,因为这样做,只会将父类的函数给之间覆盖掉(通过子类去调用父类函数,调用不起来,这是在编译器在运行时候,如果发现所碰到的函数在子类中有,就只会在子类中找对应的函数名称的函数,不会再去父类中去找了,那怕发现子类中的这个函数名称一致,但参数不一致,也只会报错,说没找到,而不会再去父类中去找了),如果非想达到重载的功能,就在子类中添加完父类的重载函数后,想去调用父类的函数时,加上父类的作用域符号,显式的写出来,这样才能调用在父类中定义的同名函数,如上段代码那样:
c1.Parent::func();
总体代码
dm16_重载重写重定义.cpp
#include <iostream>
using namespace std;
//重写 重载 重定义
//重写发生在2个类之间
//重载必须在一个类之间
//重写分为2类
//1 虚函数重写 将发生多态
//2 非虚函数重写 (重定义)
class Parent
{
//这个三个函数都是重载关系
public:
void abc()
{
printf("abc");
}
virtual void func()
{
cout<<"func() do..."<<endl;
}
virtual void func(int i)
{
cout<<"func() do..."<<i<<endl;
}
virtual void func(int i, int j)
{
cout<<"func() do..."<<i<< " "<<j<<endl;
}
virtual void func(int i, int j, int m , int n)
{
cout<<"func() do..."<<i<< " "<<j<<endl;
}
protected:
private:
};
class Child : public Parent
{
public:
void abc()
{
printf("child abc");
}
/*
void abc(int a)
{
printf("child abc");
}
*/
virtual void func(int i, int j)
{
cout<<"func(int i, int j) do..."<<i<< " "<<j<<endl;
}
virtual void func(int i, int j, int k)
{
cout<<"func(int i, int j) do.."<< endl;
}
protected:
private:
};
//重载重写和重定义
void main()
{
//: error C2661: “Child::func”: 没有重载函数接受 0 个参数
Child c1;
//c1.func();
//子类无法重载父类的函数,父类同名函数将被名称覆盖
c1.Parent::func();
//1 C++编译器 看到func名字 ,因子类中func名字已经存在了(名称覆盖).所以c++编译器不会去找父类的4个参数的func函数
//2 c++编译器只会在子类中,查找func函数,找到了两个func,一个是2个参数的,一个是3个参数的.
//3 C++编译器开始报错..... error C2661: “Child::func”: 没有重载函数接受 4 个参数
//4 若想调用父类的func,只能加上父类的域名..这样去调用..
c1.func(1, 3, 4, 5);
//c1.func();
//func函数的名字,在子类中发生了名称覆盖;子类的函数的名字,占用了父类的函数的名字的位置
//因为子类中已经有了func名字的重载形式。。。。
//编译器开始在子类中找func函数。。。。但是没有0个参数的func函数
cout<<"hello..."<<endl;
system("pause");
return ;
}
来源:CSDN
作者:恋蛩音
链接:https://blog.csdn.net/qq_17846375/article/details/104107854