C++基础:虚函数、重载、覆盖、隐藏<转>
转自:http://www.2cto.com/kf/201404/291772.html
虚函数总是跟多态联系在一起,引入虚函数可以使用基类指针对继承类对象进行操作!
虚函数:继承接口(函数名,参数,返回值),但是实现不继承(函数体)
非虚函数:继承接口,也继承实现;
1)虚析构函数(当一个类打算作为基类使用时候,其析构函数必须是虚函数)
构造函数可以为虚函数吗? 不可以,在生成对象的时候,必须向编译器明确指定要生成什么类型的对象,因而不存在虚函数的问题;只有当对象已经存在,我用什么接口去操作它的问题;
例子:
class A
{
public:
A();
virtual~A();
};
class B: public A
{
public: 
B();
~B();
};
int main()
{
A *pA=new B; //调用B的构造函数
delete pA; 
return 0; 
}
这里通过指针A去调用B类的析构函数,但是如果 ~A()不是虚析构函数,就不存在多态,就会去调用A中的析构函数,最后结果可能是B对象中的A成分被析构了,其他 还残留;所以当一个类作为基类时候,其析构函数必须是虚函数,这样防止出现析构不完全的情况;
2)当虚函数出现在构造、析构函数中时(即在构造函数中调用虚函数),函数退化为普通函数。为什么? <>中条款
例子:(转自<>中条例9)
class Transaction
{
public:
Transaction();
virtual void LogTransaction() const = 0;
// ...
};
Transaction::Transaction()
{
// ...
LogTransaction();
}
class BuyTransaction : public Transaction
{
public:
virtual void LogTransaction() const;
// ...
};
这里调用BuyTransaction的构造函数,因为BuyTransaction是继承类所以先调用基类的构造函数,此时派生类独有的那部分还未初始化,<>中这么解释:“这个对象内的BuyTransaction成分还未初始化,最安全的办法是当他不存在,对象在derived成分还未初 始化时该对象不会成为一个derived对象”所以Transaction 的构造函数会调用基类的 LogTransaction() const;而且此处是个纯虚函数,会报错
3)虚函数与覆盖,重载,隐藏
重载首先出现在非继承关系当中,当同一个类中,两个函数的参数不同,名字相同,返回值类型无所谓(函数返回值不作为重载的参考,因为函数调用时候不出现返回值);
注意两个函数可以仅仅因为const与非const的差别来实现重载;
虚函数与覆盖均出现在一个继承体系中,覆盖针对的是普通函数,当父类子类中出现同名(相同返回值,相同参数,相同函数名)要求绝对一致;
虚函数在父类子类中,首先在父类中声明该函数为virtual,那么子类可以重新定义该函数的实现,这里主要涉及多态,就是覆盖的情况加上virtual,通过指针或者引用实现多态;
隐藏显得简单粗暴,在继承类中只要出现于父类同名(只要求同样的函数名/变量名,其他返回值,virtual 非virtual不管)的函数,则用对象调用同名函数时候,基类对应的同名函数、变量隐藏,如果要访问其父类的同名成员应该明确使用 基类名::成员来访问;
例子:
class A
{
public:
virtual ~A(){};
void process(int i,char c); //重载,编译期间即可确定该调用哪个函数
char process(double d,int c); //只要函数名相同,返回无所谓,参数不同
void process(int i); 
void process(int i)const; // 此处相当于void process(const A *this,int i);
void process(consttint i); //这里仅仅因为const属性不同即可实现重载
virtual int foo(int, char){...}; 
int foo2(){};
void foo3(int,int ){};
}
class B: public A
{
public:
int foo(int ,char){...}; //虚函数,这里函数接口要严格一致(大部分编译器要求返回值也要一致)
int process(){...}; //隐藏基类函数 
int foo2(){}; // 这里不含虚属性,会覆盖
int foo3(){return 0;}; //会隐藏A类的foo3
}
int main()
{
B b;
A *pA=&b;
pA->foo2(); //这里调用A类的foo2();不涉及多态;
pA->foo(3,'c'); //B类foo() 涉及多态
}
总结:
1)覆盖与虚函数是一对兄弟,要求函数的返回值,函数名,参数严格一致,虚函数是覆盖加上virtual的情况;
2) 隐藏是覆盖的推广,覆盖是隐藏的特例,只要求函数名一样,其他不管,在继承体系中,子类的同名函数会将父类的同名函数隐藏;
3)当使用指针时候,指向基类的指针会根据实际对象的类型,选择相应的虚函数执行,如果派生类没有重新定义基类的虚函数,那么依然执行基类的虚函数;
4)当不存在虚函数的情况下,使用基类的指针,不会下降到派生类中去搜索函数;所以virtual属性相当于告诉基类指针:当执行我时,请到相应对象中搜索对应的虚函数;
5)纯虚函数所在的类是抽象类,不能实例化,定义了纯虚函数意味着这个函数只能为父类,其负责定义接口而不负责实现;
6)当使用对象来调用相应的函数时候,主要考虑的是对基类同名函数的隐藏(包括覆盖),而不需要考虑多态;
7)注意构造析构函数中不能调用虚函数,当执行派生类的构造函数时候,先构造的是其基类成分,再执行派生类成分的构造,虚函数此时无意义;
8)c++是个细节非常多,非常复杂的语言;
C++基础:虚函数、重载、覆盖、隐藏<转>的更多相关文章
- C++重载覆盖隐藏
		
写一个程序,各写出重载覆盖 1 // // main.cpp // 2013-7-17作业2 // // Created by 丁小未 on 13-7-17. // Copyright (c) 201 ...
 - C++11显式虚函数重载
		
[C++11显式虚函数重载] 在子类中给重载的虚函数加上override, 可以让编译器检察基类是否有这一虚函数.此功能适用于当基类原有的虚函数发生变化,即相当于编译期检察. 而基类,可以给函数加上f ...
 - C++ 11 学习3:显示虚函数重载(override)
		
5.显示虚函数重载 在 C++ 里,在子类中容易意外的重载虚函数.举例来说: struct Base { virtual void some_func(); }; struct Derived : B ...
 - c++ 继承 虚函数与多态性 重载 覆盖 隐藏
		
http://blog.csdn.net/lushujun2011/article/details/6827555 2011.9.27 1) 定义一个对象时,就调用了构造函数.如果一个类中没有定义任何 ...
 - 虚函数重载(overwrite) 继承覆盖问题
		
引言 类接口需要添加默认参数,以适应不同情况调用, 但是clang-tidy 不允许在接口上设置默认参数,ps: 可能担心继承类里接口重新设置新默认参数而导致误用的情况 #include <st ...
 - c/c++:重载 覆盖 隐藏 overload override overwrite
		
http://www.cnblogs.com/qlee/archive/2011/07/04/2097055.html 成员函数的重载.覆盖与隐藏成员函数的重载.覆盖(override)与隐藏很容易混 ...
 - c++中  重载   覆盖   隐藏的区别   附加 mutable笔记
		
成员函数被重载的特征有: 1) 相同的范围(在同一个类中): //2) 函数名字相同: 3) 参数不同: 4) virtual关键字可有可无. 覆盖的特征有: 1) 不同的范围(分别位于派生类与基类) ...
 - C++基础--虚函数和纯虚函数
		
虚函数的一种重要的应用是在子类重写父类方法上,一般都是在父类中声明的时候用关键字virtual修饰. 在C++中,一个父类的对象指针是可以指向子类的实例化对象,这个时候可以用该对象指针来访问父类的成员 ...
 - C++中的重载,隐藏,覆盖,虚函数,多态浅析
		
直到今日,才发现自己对重载的认识长时间以来都是错误的.幸亏现在得以纠正,真的是恐怖万分,雷人至极.一直以来,我认为重载可以发生在基类和派生类之间,例如: class A { public: void ...
 
随机推荐
- 支持lua的框架和ide
			
1.Kony http://mobilehub.io/products/kony 2.CryEngine http://mobilehub.io/products/cryengine 3.Dragon ...
 - Flex AIR组件
			
1.FileSystemComboBox .directory = File.appli / desk/doc / directoryChange 2.FileSystemTree可返回 好用 ...
 - STL树
			
前几天觉得STL中没有树和图真是一种莫大的遗憾啊,但是在网上搜了搜,发现其实可以用容器很简单的构造树. 还是废话少说上代码: struct TreeNode{ DataType data; // Da ...
 - Django - 导出项目依赖库到 requirements.txt
			
两种方法: 虚拟环境: 使用 pip freeze pip freeze > requirements.txt # 这种方式推荐配合 virtualenv ,否则会把整个环境中的包都列出来. 只 ...
 - (水题)Codeforces - 4C - Registration system
			
https://codeforces.com/problemset/problem/4/C 用来哈希的一道题目,用map也可以强行过,但是性能慢了6倍,说明是在字符串比较的时候花费了接近6倍的时间. ...
 - 让group tableview每个section拥有阴影和圆角
			
#import <UIKit/UIKit.h> @class GroupShadowTableView; @protocol GroupShadowTableViewDelegate &l ...
 - Mac下intellij IDEA新建javaweb项目
			
intellij IDEA可以说是非常好用的工具,本人用来开发java.比eclipse等好用太多了.谁用谁知道,当然只是开发工具而已,用什么都无所谓.大牛们都用记事本编程呢. 本文帮助新手创建一个j ...
 - 【书评】【不推荐】《TensorFlow:实战Google深度学习框架》(第2版)
			
参考书 <TensorFlow:实战Google深度学习框架>(第2版) 这本书我老老实实从头到尾看了一遍(实际上是看到第9章,刚看完,后面的实在看不下去了,但还是会坚持看的),所有的代码 ...
 - Eclipse mybatis中XML的自动提示
			
1. 从mybatis-3.1.1.jar中解压出dtd文件 2. 3. 复制红线处内容 4. 将上步中内容粘贴到key中
 - math(2018.10.27)
			
20%的数据直接暴搜就行,接下来我们考虑哪些数不能够出现在同一个集合中,就连一 条边,我们会发现前