c++继承关系中成员函数的重载、重写、重定义之间的区别
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c++继承关系中成员函数的重载、重写、重定义之间的区别,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3787字,纯文字阅读大概需要6分钟。
内容图文
1、Override、Overload、Redefine
-
Overload
重载只能发生在类内部,不能发生在子类和父类的继承中。具体来说,如果子类中有父类同名、同返回值类型,但是不同参数列表,这两个在不同类的函数是不能发生重载的。 -
Override
重写即就是子类将父类中的方法进行改写。在实例化Parent *p = new Son()
,即创建指针类型为父类,指向子类空间的指针,能看到重写和重定义的区别。 -
Redefine
重定义亦是发生在在继承的过程中,这个和重写容易发生混淆。主要区别根据父类中被重写或重定义的成员函数有无virtual
关键字来讨论。如果没有virtual
关键字,只要函数名相同,都会发生函数的重定义,或者说隐藏,即子类成员函数隐藏父类同名的成员函数;如果有virtual
关键字,首先要保证返回值类型要相同(个人在测试中发现,在子类中,只有将保持返回值类型、函数名相同,才能进行下一步的重写或重定义),再判断是发生重载还是重定义,如果参数列表相同,则发生重写,如果不相同,则是重定义。
2、三者之间的区别
-
重载 overload
- 发生在相同的作用域(子类和父类不在同一个作用域)
- 函数名要相同
- 参数列表不同,包括参数类型、参数个数、参数的顺序
- 有无
virtual
关键字都可以发生 - 返回值可以不同
-
重写 override
- 不同的作用域(两个同名函数分别在父类和子类)
- 相同的函数名
- 相同的参数列表
- 被重写父类中的成员函数必须有关键字'virtual'
- 相同的返回值类型
- 被重写的成员函数访问权限可以被修改,
public
、protect
或者其他。
-
重定义 redefine
- 不同的作用域
- 函数名相同
- 返回值类型可以不同(没有关键字
virtual
的情况),但是如果有virtual
关键字,必须保证返回类型相同,否则编译报错。 - 父类函数没有关键字
virtual
,参数列表可同可不同;父类函数有关键字virtual
,参数列表必须不同。
举个例子说明一下:
class Base{
public:
int param3 = 0;
void func1(){cout<<"This is Base::func1()"<<endl;}
void func2(int a){cout<<"This is Base::func2(int a)"<<endl;}
void func2(char c){cout<<"This is Base::func2(char c)"<<endl;}
void func3(){cout<<"This is Base::func3()"<<endl;}
virtual void func4(){cout<<"This is Base::func4()"<<endl;}
virtual void func5(){cout<<"This is Base::func5()"<<endl;}
virtual int func6(){cout<<"This is int Base::func6()"<<endl;}
};
class Son: public Base
{
public:
int param = 1;
int func1(){cout<<"This is Son::func1()"<<endl;}
void func2(double e){cout<<"This is Son::func2()"<<endl;}
void func3(){cout<<"This is Son::func3()"<<endl;}
void func4(){cout<<"This is Son::func4()"<<endl;}
void func5(int a){cout<<"This is Son::func5(int a)"<<endl;}
// double func6(){cout<<"This is Son::func6()"<<endl;}
};
int main() {
Son s;
Base b;
Base *bp = new Son();
s.func1();
s.func2(1.1);
s.func2('c');
s.func4();
s.func5(2);
cout<<"--------------------------------"<<endl;
b.func1();
b.func2(1);
b.func2('c');
b.func3();
cout<<"--------------------------------"<<endl;
bp->func1();
bp->func2(1);
bp->func2('e');
bp->func3();
bp->func4();
bp->func5();
return 0;
}
输出如下:
This is Son::func1()
This is Son::func2()
This is Son::func2()
This is Son::func4()
This is Son::func5(int a)
\--------------------------------
This is Base::func1()
This is Base::func2(int a)
This is Base::func2(char c)
This is Base::func3()
\--------------------------------
This is Base::func1()
This is Base::func2(int a)
This is Base::func2(char c)
This is Base::func3()
This is Son::func4()
This is Base::func5()
分别创建子类、父类、指针类型为父类指向子类空间的指针。(1)父类中的func2发生重载,主要在父类内部产生(应该说相同作用域),因为给s.func2('c')
传入字符的时候,只会调用子类函数,不会调用父类的func2(char c)
。而子类中的func2
对父类的func2
发生了重定义,并对其做了隐藏,所以调用的时候才会调用到子类的func2(double )
。从s.func1()
、s.func2()
、s.func3()
都发生了重定义,所以在继承的过程中,如果没有virtual
关键字,只要函数名相同,不管参数类型、返回值类型,都会发生重定义。(2)针对有virtual
关键字的情况,在函数名相同的情况下,首先要保证返回值类型相同,否则编译不过,如果参数列表相同,则发生重写,不同则发生重定义,例如bp->func4()
和bp->func5()
,这里bp调用函数的处理取决于是否重写的函数(虚函数的特性)。
参考文献
内容总结
以上是互联网集市为您收集整理的c++继承关系中成员函数的重载、重写、重定义之间的区别全部内容,希望文章能够帮你解决c++继承关系中成员函数的重载、重写、重定义之间的区别所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。