(转)内联(inline)函数与虚函数(virtual)的讨论

本文转自: http://topic.csdn.net/t/20051220/09/4469273.html

函数的inline属性是在编译时确定的, 然而,virtual的性质是在运行时确定的,这两个不能同时存在,只能有一个选择,文件中的inline关键字只是对编译器的建议,编译器是否采纳是编译器的事情。

1.内联函数是个静态行为,而虚函数是个动态行为,他们之间是有矛盾的。

2.我们之所以能看到一些象内联函数的虚函数,是因为某个函数是否是内联函数不是由我们说的算,而是由编译器决定的。我们只能向编译器建议,某个函数可以是内联函数(inline关键字),但是编译器有自己的判断法则。所以可能出现这样的情况:

2.1我们用inline声明的函数却没有inline

2.2我们没有用inline声明的函数却是inline

2.3对于inline函数,编译器仍然将它编译成一个有地址的函数

所以,情况比较复杂,从high-level来看的话很难判断函数是否是inline的,如果从low-level来看的话就比较清晰,非内联函数遵从函数调用机制,在汇编中用call来调用。内联函数则没有这些。

inline函数表示该函数是内联的,它建议编译程序在调用该函数的地方直接将函数的代码展开来插入caller的代码中.这个只是一种指示,至于会不会被内联,编译程序还会根据被声明为inline的函数的内部结构如:是否包含循环,复杂的函数调用等等来选择是否inline。

1.虚函数肯定不会被内联这一点毋庸置疑,因为虚函数只有到了Runtime才能被识别到底是哪一个被调用,而内联是编译期就会将代码展开并安插这个明显不是一回事。

2.inline有两种表现方式一种就是以inline在实现文件中(.cpp)指出这被称为显示内联,另外一种就如你所说类的声明和定义放入同一个文件这称为隐式内联,但是还是如前面所说inline只是一个提示符至于会不会内联还是由编译程序说了算。

 1 #include <iostream>
 2 using namespace std;
 3 class A
 4 {
 5 public:
 6     inline  virtual void virFUn() {  //类的成员函数作为回调函数 static方式实现
 7         cout<< "我是A中虚函数,inline在这不起作用!"<<endl;
 8     }
 9     void f();
10 };
11
12 inline  void A::f() {
13     cout<< "我是真正的内联函数,不能同时设置为虚函数!"<<endl;
14 }
15
16 class B: public A
17 {
18 public:
19     virtual void virFUn()  {
20         cout<< "我是B中虚函数!"<<endl;
21     }
22 };
23 int main()
24 {
25     A * pa;
26     B b;
27     pa = &b;
28     pa->virFUn();
29     A a;
30     a.f();
31 }
时间: 2024-08-09 23:57:10

(转)内联(inline)函数与虚函数(virtual)的讨论的相关文章

内联函数与虚函数

如果函数已经被声明为inline, 内联函数已经在编译期间它的调用点上就被展开; 而虚拟函数调用的决定则要等到运行时刻在执行程序内部的每个调用点上系统根据被调用对象的实际基类或派生类的类型来决定选择哪一个虚拟函数实例. 内联不是强制性的,你只是向编译器提出这个建议,允许它在可以内联的时候采取内联形式.而虚函数本身就是一个函数,只是在多态的情况下,它要到执行时才能确定调用的函数,所以这样的特性阻止了虚函数的内联.但,要注意,只是在多态的情况下(多态不用我解释吧).如果是静态的调用,编译器还是会采用

函数内联 inline,__inline,__forceinline

? 感谢大佬的总结[http://www.cnblogs.com/xuemaxiongfeng/articles/2464850.html] ● 存储限定符 __inline 与关键字 inline 的语义完全相同,不影响函数的类型,建议编译器在合理的情况下内联编译 C/C++ 函数 ● 内联减少了函数调用的开销,但却增加了代码量 ● inline 仅用于 C++,__inline和 __forceinline 用于 C/C++ ● 编译器处理内联的情况: ■ 使用 /clr 编译选项时,如果函

C++ 虚函数&amp;纯虚函数&amp;抽象类&amp;接口&amp;虚基类(转)

http://www.cnblogs.com/fly1988happy/archive/2012/09/25/2701237.html 1. 多态 在面向对象语言中,接口的多种不同实现方式即为多态.多态是指,用父类的指针指向子类的实例(对象),然后通过父类的指针调用实际子类的成员函数. 多态性就是允许将子类类型的指针赋值给父类类型的指针,多态是通过虚函数实现的. 多态可以让父类的指针有“多种形态”,这是一种泛型技术.(所谓泛型技术,就是试图使用不变的代码来实现可变的算法). 2. 虚函数 2.1

对于Java中main函数为虚函数以及多态的一点理解

Question: 1.在Java中,由于main函数的定义为: public static void main(String[] args):那么要想在main函数中调用其余的函数的话,就必须将定义为static.另外,调用其他类编写的成员函数时,却不需要该成员函数为静态的,这是为什么? 分析: 静态方法是属于某一个类所有,而非静态方法是属于某类的对象所有.也就是说,要想调用非静态方法,必须先调用new来得到一个类的对象,系统为其分配内存,然后才能通过该对象访问相应的非静态成员函数.而静态方法

虚函数/纯虚函数/抽象类/接口/虚基类

1.多态 在面向对象语言中,接口的多种不同实现方式即为多态.多态是指,用父类的指针指向子类的实例(对象),然后通过父类的指针调用实际子类的成员函数. 在Java中,没有指针,就直接用父类实例化子类对象 多态性就是允许将子类类型的指针赋值给父类类型的指针,多态是通过虚函数实现的,多态可以让父类的指针有“多种形态”,这是一种泛型技术. 所谓泛型技术,就是试图使用不变的代码来实现可变的算法 2.虚函数 在基类的类定义中,定义虚函数的一般形式: Virtual 函数返回值类型 虚函数名(形参表){ 函数

纯虚函数和虚函数

首先:强调一个概念定义一个函数为虚函数,不代表函数为不被实现的函数.定义他为虚函数是为了允许用基类的指针来调用子类的这个函数.定义一个函数为纯虚函数,才代表函数没有被实现.定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数.1.简介假设我们有下面的类层次: class A { public: virtual void foo() { cout<<"A::foo() is called"<<endl; } }; class

[转]什么是C++虚函数、虚函数的作用和使用方法

我们知道,在同一类中是不能定义两个名字相同.参数个数和类型都相同的函数的,否则就是“重复定义”.但是在类的继承层次结构中,在不同的层次中可以出现名字相同.参数个数和类型都相同而功能不同的函数.例如在例12.1(具体代码请查看:C++多态性的一个典型例子)程序中,在Circle类中定义了 area函数,在Circle类的派生类Cylinder中也定义了一个area函数.这两个函数不仅名字相同,而且参数个数相同(均为0),但功能不同,函数体是不同的.前者的作用是求圆面积,后者的作用是求圆柱体的表面积

C++纯虚函数、虚函数、实函数、抽象类,重载、重写、重定义

首先,面向对象程序设计(object-oriented programming)的核心思想是数据抽象.继承.动态绑定.通过数据抽象,可以使类的接口与实现分离,使用继承,可以更容易地定义与其他类相似但不完全相同的新类,使用动态绑定,可以在一定程度上忽略相似类的区别,而以统一的方式使用它们的对象. 虚函数的作用是实现多态性(Polymorphism),多态性是将接口与实现进行分离,采用共同的方法,但因个体差异而采用不同的策略.纯虚函数则是一种特殊的虚函数.虚函数联系到多态,多态联系到继承. 一.虚函

【反汇编分析】C++成员函数和虚函数

本节通过反汇编研究C++非static成员函数和虚函数的执行流程: 代码片段如下 class Animal { public: virtual void print() { cout << "Animal::print "<< endl; } void print2() { cout << "Animal::print2 "<< endl; } }; class Dog : public Animal { public