C++中有哪些函数不能声明为虚函数
来源:互联网 发布:淘宝店提高销量 编辑:程序博客网 时间:2024/04/28 15:31
转自:http://blog.csdn.net/ta893115871/article/details/8194836
一、首先回顾下什么是虚函数及其作用,以便更好理解什么函数不能声明或定义为虚函数:
1. 定义:
虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数的一般形式:
virtual 函数返回值类型 虚函数名(形参表) { 函数体 }
2. 作用:
虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在基类的派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具有相同的形参个数和形参类型,以实现统一的接口,不同定义过程。如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数。
当程序发现虚函数名前的关键字virtual后,会自动将其作为动态联编处理,即在程序运行时动态地选择合适的成员函数。
3. 使用方法:
动态联编规定,只能通过指向基类的指针或基类对象的引用来调用虚函数,其格式:
指向基类的指针变量名->虚函数名(实参表)
或
基类对象的引用名. 虚函数名(实参表)
4. 其它说明:
虚函数是C++多态的一种表现:
例如:子类继承了父类的一个函数(方法),而我们把父类的指针指向子类,则必须把父类的该函数(方法)设为virtual(虚函数)。 使用虚函数,我们可以灵活的进行动态绑定,当然是以一定的开销为代价。 如果父类的函数(方法)根本没有必要或者无法实现,完全要依赖子类去实现的话,可以把此函数(方法)设为virtual 函数名=0 我们把这样的函数(方法)称为纯虚函数。 如果一个类包含了纯虚函数,称此类为抽象类 。常见的不能声明为虚函数的有:普通函数(非成员函数);静态成员函数;内联成员函数;构造函数;友元函数。
设置虚函数须注意:
1:只有类的成员函数才能说明为虚函数;
2:静态成员函数不能是虚函数;
3:内联函数不能为虚函数;
4:构造函数不能是虚函数;
5:析构函数可以是虚函数,而且通常声明为虚函数。
#include <iostream>
using namespace std;
class Base{
public:
virtual void f1(){cout < < "Father " < <endl;}
};
class Drived1:public Base{
public:
void f1(){cout < < "Son1 " < <endl;}
};
class Drived2:public Base{
public:
void f1(){cout < < "Son2 " < <endl;}
};
void myPrint(Base* pBs){
pBs-> f1();
}
int main()
{
Base father;
Drived1 son1;
Drived2 son2;
myPrint(&father);
myPrint(&son1);
myPrint(&son2);
system( "PAUSE ");
return 0;
}
输出:
Father
Son1
Son2
你可以发现,虽然f1在基类中定义的,按理说应该是内联函数,但是它仍然可以成为虚函数。
你写inline virtual void f(),不能保证函数f()一定是内联的,只能保证f()是虚函数(从而保证此函数一定不是内联函数)
对于问题:
到底内联函数能不能成为虚函数?
答案是不能.问题是你不能够确定一个函数到底是不是inline的.inlien关键字只是对编译器的一个建议:"如果有可能,请把此函数搞成inline的"
1.为什么C++不支持普通函数为虚函数?
普通函数(非成员函数)只能被overload,不能被override,声明为虚函数也没有什么意思,因此编译器会在编译时邦定函数。
多态的运行期行为体现在虚函数上,虚函数通过继承方式来体现出多态作用,顶层
2.为什么C++不支持构造函数为虚函数?
这个原因很简单,主要是从语义上考虑,所以不支持。因为构造函数本来就是为了明确初始化对象成员才产生的,然而virtual function主要是为了再不完全了解细节的情况下也能正确处理对象。另外,virtual函数是在不同类型的对象产生不同的动作,现在对象还没有产生,如何使用virtual函数来完成你想完成的动作。(这不就是典型的悖论)
(1)构造函数不能被继承,因而不能声明为virtual函数
3.为什么C++不支持内联成员函数为虚函数?
其实很简单,那内联函数就是为了在代码中直接展开,减少函数调用花费的代价,虚函数是为了在继承后对象能够准确的执行自己的动作,这是不可能统一的。(再说了,inline函数在编译时被展开,虚函数在运行时才能动态的邦定函数)
inline函数和virtual函数有着本质的区别,inline函数是在程序被编译时就展开,在函数调用处用整个函数体去替换,而virtual函数是在运行期才能够确定如何去调用的,因而inline函数体现的是一种编译期机制,virtual函数体现的是一种运行期机制。此外,一切virtual函数都不可能是inline函数。
4.为什么C++不支持静态成员函数为虚函数?
这也很简单,静态成员函数对于每个类来说只有一份代码,所有的对象都共享这一份代码,他也没有要动态邦定的必要性。不能被继承,只属于该类。
5.为什么C++不支持友元函数为虚函数?
因为C++不支持友元函数的继承,对于没有继承特性的函数没有虚函数的说法。友元函数不属于类的成员函数,不能被继承。
eg:
- /*
- * main.cpp
- *
- * Created on: 2012-11-17
- * Author: china
- */
- #include <iostream>
- using namespace std;
- class B {
- public:
- B() {
- cout << "基类构造" << endl;
- }
- /*在类的继承中,如果有基类指针指向派生类,那么用基类指针delete时,如果不定义成虚函数,派生类中派生的那部分无法析构。
- * 你可以吧virtual去掉试一下
- * 因此在类的继承体系中,基类的析构函数不声明为虚函数容易造成内存泄漏。所以如果你设计一定类可能是基类的话,必须要声明其为虚函数。
- * */
- virtual ~B() {
- cout << "基类析构" << endl;
- }
- virtual void func() {
- cout << "基类的func()" << endl;
- }
- private:
- };
- class D :public B{
- public:
- D() {
- cout << "派生类构造" << endl;
- }
- ~D() {
- cout << "派生类析构" << endl;
- }
- void func() {
- cout << "派生类的func()" << endl;
- }
- private:
- };
- int main(int argc, char **argv) {
- D d; //调用构造先有对象
- B*p = &d;
- p->func(); //再体现多态机制
- p = new D(); //再调用构造
- p->func(); //再体现多态机制
- delete p;
- return 0;
- C++中有哪些函数不能声明为虚函数
- c++有哪些函数不能声明为虚函数
- C++中不能声明为虚函数的有哪些函数
- C++中不能声明为虚函数的有哪些函数
- C++中不能声明为虚函数的有哪些函数
- C++中不能声明为虚函数的有哪些函数
- C++中不能声明为虚函数的有哪些函数
- C++中不能声明为虚函数的有哪些函数
- C++中不能声明为虚函数的有哪些函数
- C++中不能声明为虚函数的有哪些函数(未读)
- C++中不能声明为虚函数的有哪些函数
- C++中哪些函数不能被声明为虚函数
- 哪些函数不能声明为虚函数
- 哪些函数不能声明为虚函数
- 哪些函数不能被声明为虚函数
- 【c++】不能被声明为虚函数的C++函数
- C++中不能被声明为虚函数的函数
- C++面试题之哪些函数不能声明为虚函数
- Android Studio 配置优化
- AVL树的思想与C++实现
- LeetCode -- Construct Binary Tree from Inorder and Postorder Traversal
- jsp实现分页和页面跳转功能
- 引擎磨合 (Break In) 的秘密
- C++中有哪些函数不能声明为虚函数
- 线程程序编译出错 undefined reference to `pthread_create'
- jQuery UI基础----2jQuery UI Interractions-draggable(可拖放性
- 拍照图片旋转问题
- LeetCode -- Factorial Trailing Zeroes
- 计算机视觉、机器学习相关领域论文和源代码大集合
- Codeforces Yandex.Algorithm 2011 Round 1 85D 线段树
- LeetCode -- Gas Station
- HDU 3549 Flow Problem 最大流模板题