-
2019-02-25 11:37:29
什么样的函数不能声明为虚函数?
- 不能被继承的函数。
- 不能被重写的函数。
1)普通函数
普通函数不属于成员函数,是不能被继承的。普通函数只能被重载,不能被重写,因此声明为虚函数没有意义。因为编译器会在编译时绑定函数。
而多态体现在运行时绑定。通常通过基类指针指向子类对象实现多态。
2)友元函数
友元函数不属于类的成员函数,不能被继承。对于没有继承特性的函数没有虚函数的说法。
3)构造函数
首先说下什么是构造函数,构造函数是用来初始化对象的。假如子类可以继承基类构造函数,那么子类对象的构造将使用基类的构造函数,而基类构造函数并不知道子类的有什么成员,显然是不符合语义的。从另外一个角度来讲,多态是通过基类指针指向子类对象来实现多态的,在对象构造之前并没有对象产生,因此无法使用多态特性,这是矛盾的。因此构造函数不允许继承。
4)内联成员函数
我们需要知道内联函数就是为了在代码中直接展开,减少函数调用花费的代价。也就是说内联函数是在编译时展开的。而虚函数是为了实现多态,是在运行时绑定的。因此显然内联函数和多态的特性相违背。
5)静态成员函数
首先静态成员函数理论是可继承的。但是静态成员函数是编译时确定的,无法动态绑定,不支持多态,因此不能被重写,也就不能被声明为虚函数。
更多相关内容 -
哪些函数不能设置为虚函数
2018-08-06 22:27:46设置虚函数须注意: ...虚函数可以实现多态,那么那些函数不能申明为虚函数呢? 1.普通的函数 因为普通函数只能被overload,不能被override,也不能被继承,所以在编译的时候就绑定函数,所以不能申明为virt...
设置虚函数须注意:
1:只有类的成员函数才能说明为虚函数;
2:静态成员函数不能是虚函数;
3:内联函数不能为虚函数;
4:构造函数不能是虚函数;
5:析构函数可以是虚函数,而且通常声明为虚函数。虚函数可以实现多态,那么那些函数不能申明为虚函数呢?
1.普通的函数
因为普通函数只能被overload,不能被override,也不能被继承,所以在编译的时候就绑定函数,所以不能申明为virtual,没有意义!
2.构造函数
这个也很简单。主要因为构造函数是用来确定初始化对象的,而virtual主要是为了在不了解具体的情况下实现动态绑定,调用不同类型中合适的成员函数而存在的,现在对象都没产生,怎么能实现多态呢。一个是为了具体化,一个是为了在不同对象类型中确定合适的函数,这是不可能的!
此外,构造函数不能被继承,所以不能virtual;构造函数是系统默认提供或者自己写的,并且和类名相同,就算继承了也不是自己的了,所以不能被继承;
构造函数是在为了创建初始化对象存在的,对象不存在实现多态是不可能的;
3.内联函数
inline函数在编译时被展开,在调用处将整个函数替换为代码块,省去了函数跳转的时间,提高了SD,减少函数调用的开销,虚函数是为了继承后对象能够准确的调用自己的函数,执行相应的动作。
主要的原因是:inline函数在编译时被展开,用函数体去替换函数,而virtual是在运行期间才能动态绑定的,这也决定了inline函数不可能为虚函数。(inline函数体现的是一种编译机制,而virtual体现的是一种动态运行机制)
4.静态成员函数
静态成员函数是类的组成部分,但是不是任何对象的组成部分,所有对象共享一份,没有必要动态绑定,也不能被继承【效果能,但机理不能。静态成员函数就一份实体,在父类里;子类继承父类时也无需拷贝父类的静态函数,但子类可以使用父类的静态成员函数】,并且静态成员函数只能访问静态变量。所以不能为virtual。
5.友员函数
友员函数不是类的成员函数,C++不支持友员被继承,所以不能为virtual。
-
什么函数不能声明或定义为虚函数
2015-09-04 14:59:12一、首先回顾下什么是虚函数及其作用,以便更好理解什么函数不能声明或定义为虚函数: 1. 定义: 虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数的一般...一、首先回顾下什么是虚函数及其作用,以便更好理解什么函数不能声明或定义为虚函数:
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但实际上不能inline的函数自动改为不inline的。至于编译器会不会将inline and virtual的函数照模照样的实现,与编译器及优化方式有关。要想成为虚函数,必须能够被取到地址.内联函数不能被取到地址所以不能成为虚函数.
你写inline virtual void f(),不能保证函数f()一定是内联的,只能保证f()是虚函数(从而保证此函数一定不是内联函数)
对于问题:
到底内联函数能不能成为虚函数?
答案是不能.问题是你不能够确定一个函数到底是不是inline的.inlien关键字只是对编译器的一个建议:"如果有可能,请把此函数搞成inline的" -
C++中虚函数和纯虚函数定义
2020-12-22 15:32:46一个成员函数被声明为虚函数后,在同一类族中的类不能再定义一个非virtual的但与该虚函数具有相同的参数(包括个数和类型)和函数返回值类型的同名函数。 根据什么考虑是否把一个成员函数声明为虚函数? ①... -
【C++】C++中哪些函数不能被声明为虚函数
2020-07-01 13:55:35什么函数不能被声明为虚函数? 1、普通函数(非类成员函数); 2、构造函数; 3、内联函数; 4、静态成员函数; 5、友元函数; 6、不会被继承的基类的析构函数(没有必要)。 1、普通函数(非类成员函数)不能被声明...什么函数不能被声明为虚函数?
1、普通函数(非类成员函数);
2、构造函数;
3、内联函数;
4、静态成员函数;
5、友元函数;
6、不会被继承的基类的析构函数(没有必要)。1、普通函数(非类成员函数)不能被声明为虚函数;
注意:只有类的成员函数才有可能被声明为虚函数。
因为普通函数(非成员函数)只能被重载,不能被重写。声明为虚函数也没有什么意思,因此编译器会在编译时绑定函数。
2、构造函数不能被声明为虚函数;
首先说下什么是构造函数,构造函数是用来初始化对象的。虚函数的主要作用是实现多态,多态是依托于类的,多态的使用必须是在类创建以后,而构造函数是用来创建构造函数的,所以不行。
具体原因:虚表指针的初始化时在构造函数进行的,而虚函数需要放到虚表中。在调用虚函数前,必须首先知道虚表指针,就互相矛盾了。
3、内联函数inline不能被声明为虚函数;
内联函数必须有实体,是在编译时展开。内联函数就是为了在代码中直接展开,减少函数调用花费的代价。虚函数是为了在继承后对象能够准确的执行自己的动作,这是不可能统一的。还有一点,inline内联函数是在编译时被展开,虚函数实在运行时才能动态的邦定函数。
4、静态成员函数不能被声明为虚函数;
静态成员函数理论是可继承的。但是静态成员函数是编译时确定的,无法动态绑定,不支持多态,因此不能被重写,也就不能被声明为虚函数。
5、友元函数不能被声明为虚函数;
原因:C++不支持友元函数的继承,不能继承的函数指定不是虚函数。
6、不会被继承的基类的析构函数没必要被声明为虚函数;
注意:析构函数可以是虚函数,而且通常声明为虚函数。
原因:首先,析构函数执行过程是:先调用派生类的析构函数,其次再调用基类的析构函数。所以,将可能会被继承的基类的析构函数设置为虚函数,可以保证当我们new一个子类,然后使用基类指针指向该子类对象,释放基类指针时可以释放掉子类的空间,防止内存泄漏。
但是为什么说不会被继承的基类的析构函数没必要被声明为虚函数呢?
虚函数的实现需要额外的虚函数表和虚表指针,占用额外的内存。而对于不会被继承的类来说,其析构函数如果是虚函数,就会浪费内存。因此只有当需要被当作基类时的析构函数才会被设置为虚函数。这也是为什么C++默认的析构函数不是虚函数的原因。总结:
那么到底哪种函数不能被声明为虚函数呢?
其实有两点:
(1)不能被继承的函数;
(2)不能被重写的函数。 -
哪些函数可以成为虚函数,哪些函数不可以成为虚函数
2020-06-14 21:39:04拥有 Virtual 关键字的函数称之为虚函数 虚函数的作用是实现动态绑定的,也就是说程序在运行的时候动态的的选择合适的成员函数 那么,有哪些函数可以成为虚函数?那些函数不可以成为虚函数? 要成为虚函数必须... -
C++ 哪些不能为虚函数
2019-10-21 19:38:03虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数的一般形式: virtual 函数返回值类型 虚函数名(形参表){ 函数体 } 作用: 虚函数的作用是实现动态联编,... -
虚函数,虚表指针的初始化时期,静态函数能否为虚函数,哪些函数不能是虚函数
2021-12-24 15:26:36构造函数不能定义为虚函数。在构造函数中可以调用虚函数,不过此时调用的是正在构造的类中的虚函数,而不是子类的虚函数,因为此时子类尚未构造好。虚函数对应一个 vtable (虚函数表),类中存储一个 vptr -
为什么构造函数不能声明为虚函数?
2018-07-18 00:07:07构造函数不能声明为虚函数,析构函数可以声明为虚函数,而且有时是必须声明为虚函数。 构造函数不能声明为虚函数的原因是: 1 构造一个对象的时候,必须知道对象的实际类型,而虚函数行为是在运行期间确定实际类型的... -
C++中为什么构造函数不能定义为虚函数
2018-01-09 14:43:47关于C++为什么不支持虚拟构造函数,Bjarne很早以前就在C++Style and Technique FAQ里面做过回答 Avirtual call is a mechanism to get work done given partialinformation. In particular, "virtual" allows us to... -
什么函数不能声明为虚函数
2019-04-30 09:19:34一、首先回顾下什么是虚函数及其作用,以便更好理解什么函数不能声明或定义为虚函数: 1. 定义: 虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数的一般形式:... -
内联函数、构造函数、静态成员函数不可以定义为虚函数?
2019-07-02 21:20:03简单来说,我们可以将多态定义为消息以多种形式显示的能。 多态是以封装和继承为基础的。 C++ 多态分类及实现: i. 重载多态(Ad-hoc Polymorphism,编译期):函数重载、运算符重载 ii. ⼦类型多态(Subtype ... -
内联函数、构造函数、静态成员函数不可以定义为虚函数
2018-06-03 19:02:45内联函数、构造函数、静态成员函数不可以定义为虚函数 内联函数是编译时展开函数体,所以...如果构造函数定义为虚函数,则需要通过查找虚函数表来进行调用。但是构造函数是虚函数的情况下是找不到的,因为构造函数... -
虚函数 2 之虚函数的定义
2019-01-24 23:20:341、虚函数的定义 虚函数就是在基类中被关键字 virtual 说明,并在派生类中重新定义的函数。 虚函数的作用是允许在派生类中重新定义与基类同名...定义虚函数的方法如下: virtual 函数类型 函数名(形参表){ ... -
浅析C++中的虚函数
2020-12-26 06:00:00定义为virtual的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。 二、作用虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在... -
构造函数为啥不能声明为虚函数
2020-09-01 21:57:46原因: 构造一个对象的时候,必须知道对象的实际类型,而虚函数行为是运行期间确定实际类型的。 虚函数的执行依赖于虚函数表。而虚函数表在构造函数中进行初始化工作, -
C++中为什么构造函数不能为虚函数
2019-09-26 13:58:06为什么构造函数不能声明为虚函数? 1.创建一个对象必须明确指出它的类型,否则无法创建,一个对象创建成功编译器获得它的实际类型,然后去调用对应的函数,而如果构造函数声明为虚函数,会形成一个死锁,虚函数是在... -
为什么构造函数不能是虚函数?析构函数可以是虚函数吗?
2020-07-10 10:56:32构造函数不能声明为虚函数,析构函数可以声明为虚函数,而且有时是必须声明为虚函数。 抽象类中构造和析构均不能使用纯虚函数。 为什么构造函数不能声明为虚函数呢? 1、构造一个对象的时候,必须知道对象的实际... -
c++中的内联函数与虚函数,以及哪些函数不能为内联函数,
2019-04-08 21:55:31在计算机科学中,内联函数(有时称作在线函数或编译时期展开函数)是一种编程语言结构,用来建议编译器对一些特殊函数进行内联扩展(有时称作在线扩展);也就是说建议编译器将指定的函数体插入并取代每一处调用该... -
C++:为什么在继承关系中,父类的析构函数最好定义为虚函数?
2018-08-15 15:14:33如果不把父类的析构函数定义为虚函数,会有什么问题? void Test() { A* pa = new B( 0 ); //父类的指针指向了子类的对象 delete pa; // } pa是A类的指针,它指向了新创建的B类对象,在析构时,... -
构造函数为什么一般不定义为虚函数?而析构函数一般写成虚函数的原因 ?
2019-01-03 11:29:101、构造函数不能声明为虚函数 1)因为创建一个对象时需要确定对象的类型,而虚函数是在运行时确定其类型的。而在构造一个对象时,由于对象还未创建成功,编译器无法知道对象的实际类型,是类本身还是类的派生类等等... -
什么情况下析构函数需要定义为虚函数?
2017-09-26 08:22:12一、什么情况下析构函数需要定义为虚函数?答案是在实现多态时。如果单单是填空题,相信大家都可以拿满分。但说到何谓之多态,可能大家的回答不尽相同。至于多态时怎样实现的?又有什么样的作用呢?这样深入逼问下去... -
C++:基类析构函数为什么要定义为虚函数
2019-07-19 15:51:39在C++实现多态里,有一个关于 析构函数的重写问题:基类中的析构函数如果是虚函数,那么派生类的析构函数就重写了基类的析构函数。...原因:当基类指针指向派生类的时候,若基类析构函数不声明为虚函数... -
C++类中的虚函数不能为模板函数
2020-10-23 08:49:06C++类中的虚函数不能为模板函数 首先,理解模板的原理。例如,定义了一个模板函数: template<typename A> void Func(const A& a) { std::cout <<"Func(const A& a) : "<< a <<... -
构造函数不能是虚函数
2019-04-30 10:08:53构造函数为什么不能使虚函数 1.虚函数对应一个虚指针,虚指针其实是存储在对象的内存空间的。如果构造函数是虚的,就需要通过 虚指针执行那个虚函数表(编译期间生成属于类)来调用,可是对象还没有实例化,也就是... -
虚函数不能定义为内联函数
2017-12-05 20:59:47在C++中,inline关键字和virtual关键字分别用来定义c++中的内联函数和虚函数,他们在各自的场合都有其各自的应用,下面将简单介绍他们各自的功能,然后在说明为什么一个函数不能同时是虚函数和内联函数(inline) ... -
不能声明为虚函数的函数:
2017-03-13 20:08:22使用虚函数时,有两点要注意: (1)只能用virtual声明...(2)一个成员函数被声明为虚函数后,在同一类族中的类就不能再定义一个非virtual的但与该虚函数具有相同的参数(包括个数和类型)和函数返回值类型的同名函数。 -
C++之虚函数(为什么构造函数不可以声明为虚函数,析构函数可以声明为虚函数)
2018-08-01 17:29:29构造函数不能声明为虚函数,而析构函数可以声明为虚函数,在有的情景下析构函数必须声明为虚函数。 不建议在构造函数和析构函数里调用虚函数。 构造函数不能声明为虚函数的原因? 构造一个对象时,必须知道... -
C++ --类的默认成员函数是否可以被定义为虚函数
2018-05-27 20:21:06构造函数不能定义为虚函数 1.因为虚函数是存放在对象的虚表里面,如果将构造函数定义为虚函数,则构造函数也必须存放在虚表里面,但是此时对象都还没有创建也就没有所谓的虚表。 2.不将构造函数定义为虚函数,对象... -
C++:什么情况下需要将析构函数定义为虚函数?
2016-10-17 15:55:22C++:什么情况下需要将析构函数定义为虚函数。