内联函数(Inline Functions)

news/2024/5/20 4:26:38 标签: 内联函数

内联函数(Inline Functions)

一、相关日志

C++与C的不同(一)

http://blog.163.com/zhoumhan_0351/blog/static/399542272010019115933109/

必须保证每一个定义了静态对象的函数只有一个定义,故不能把定义了静态对象的函数作为内联函数

定义一个友元函数为内联函数,不会改变其友元状态,而且它仍是全局函数。

只有类的成员函数才能说明为虚函数,普能函数不行;静态成员函数不能是虚函数;内联函数不能是虚函数,即使虚函数在类的内部定义,编译时仍将其视作非内联的;析构函数可以是虚函数,而且通常声明为虚函数。

C++基础笔记(二)

http://blog.163.com/zhoumhan_0351/blog/static/39954227201012471245444/

C++基本概念(内联,模板,函数)

http://blog.163.com/zhoumhan_0351/blog/static/39954227201002202430247/

二、内联函数

1、关键点

为了既保证预处理器的效率又增加安全性,同时还能像成员函数一样可以在类中访问,C++引入内联函数

对于任何函数,编译器在它的符号表里放入函数类型(函数原型及返回值)。当编译器看到内联函数且对内联函数的分析没有发现错误时,就将对应于函数体的代码也放入符号表中。我们可以看到,编译器是对内联函数进行类型检查和转换的(在调用中,如果发现类型不匹配,则试图将其转换为正确类型,返回值类型也进行分析,如果类型不匹配,也尝试转换),而预处理宏是不行的。

假如要显式地或隐式地取函数地址,编译器也不能执行函数。只在在类声明结束后,其中的内联函数才会被计算。

//: C09:EvaluationOrder.cpp

// Inline evaluation order

class Forward {

  int i;

public:

  Forward() : i(0) {}

  // Call to undeclared function:

  int f() const { return g() + 1; }

  int g() const { return i; }

};

int main() {

  Forward frwd;

  frwd.f();

} ///:~

所以,如上程序也可运行通过,虽然g()在f()这前还没有定义。

在类外定义的成员函数想成为内联函数时,只要加上inline就可以了。

2、预处理器的更多特征

预处理器的如下二个特例,内联函数不能代替:

1)字符串定义、拼接

字符串定义的完成是用#指示,它容许取一个标志符并把它转化为字符串数组。

#define DEBUG(x) cout << #x " = " << x << endl

int main()

{

int x=1;

DEBUG(x);

return 1;

}

前面已有叙述,相关日志。

Thinking in C++前几章笔记(一)

http://blog.163.com/zhoumhan_0351/blog/static/39954227201032124942513/

2)标志粘贴

可以直接用"##"实现。允许设两个标识符并把它们粘贴在一起自动生成一个新的标识符。

#include "iostream"

using namespace std;

#define FIELD(a) char* a##_string; int a##_size

#define FIELD(a) char* a##_string; int a##_size

class Record {

  FIELD(one);

  FIELD(two);

  FIELD(three);

  // ...

}; 

int main(){

Record m;

m.

}

3、一个常用的断言程序

//: :require.h

// Test for error conditions in programs

// Local "using namespace std" for old compilers

#ifndef REQUIRE_H

#define REQUIRE_H

#include <cstdio>

#include <cstdlib>

#include <fstream>

#include <string>

inline void require(bool requirement, const std::string& msg = "Requirement failed"){

  using namespace std;

  if (!requirement) {

fputs(msg.c_str(), stderr);

fputs("\n", stderr);

exit(1);

  }

}

inline void requireArgs(int argc, int args, const std::string& msg = "Must use %d arguments") {

  using namespace std;

   if (argc != args + 1) {

 fprintf(stderr, msg.c_str(), args);

 fputs("\n", stderr);

 exit(1);

   }

}

inline void requireMinArgs(int argc, int minArgs,const std::string& msg ="Must use at least %d 

arguments") {

  using namespace std;

  if(argc < minArgs + 1) {

fprintf(stderr, msg.c_str(), minArgs);

fputs("\n", stderr);

exit(1);

  }

}

inline void assure(std::ifstream& in, const std::string& filename = "") {

  using namespace std;

  if(!in) {

fprintf(stderr, "Could not open file %s\n",

  filename.c_str());

exit(1);

  }

}

inline void assure(std::ofstream& out, const std::string& filename = "") {

  using namespace std;

  if(!out) {

fprintf(stderr, "Could not open file %s\n", 

  filename.c_str());

exit(1);

  }

}

#endif // REQUIRE_H ///:~

//: C09:ErrTest.cpp

//{T} ErrTest.cpp

// Testing require.h

//#include "../require.h"

#include <fstream>

using namespace std;

int main(int argc, char* argv[]) {

  int i = 1;

  require(i, "value must be nonzero");

  requireArgs(argc, 1);

  requireMinArgs(argc, 1);

  ifstream in(argv[1]);

  assure(in, argv[1]); // Use the file name

  ifstream nofile("nofile.xxx");

  // Fails:

//!  assure(nofile); // The default argument

  ofstream out("tmp.txt");

  assure(out);

} ///:~

输入输出流(二)

http://blog.163.com/zhoumhan_0351/blog/static/39954227201003005237697/

参考:

1、Thinking in C++

 


http://www.niftyadmin.cn/n/1098516.html

相关文章

Thinking in C++前几章笔记(二)

15、动态计算数组的大小&#xff1a; int c[]{1,2,3,4}; for(int i0;i<sizeof c/sizeof *c;i) c[i]; 16、type-safe linkage&#xff1a;Because all functions must be declared before they are used in C, the opportunity for this problem to pop up is greatly dim…

快手短信免费版

今天发布了一个利用Gsm Modem发送短信的软件&#xff0c;详情请访问 http://www.kuaishou.net 转载于:https://www.cnblogs.com/kuaishou/archive/2009/03/19/2360195.html

JavaEE的Struts2框架

Struts2的三个重要构件 核心控制器 filterDispatcher&#xff1b;逻辑组件 javaBean&#xff1b;业务控制器 Action。 Struts2的基本包 可以到官网上下载轻松版&#xff1a;struts-2.5.10-min-lib.zip。 struts.xml的配置文件的结构 < ?xml version”1.0” encoding”U…

Thinking in C++前几章笔记(1)

Thinking in C前几章笔记 1、对象&#xff1a;把问题空间中的事物和它们在解空间中表示行为称为对象。 万物皆对象&#xff0c;程序就是一组对象&#xff0c;对象之间通过发送消息互相通知做什么。创建抽象数据类型是面向对象程序设计的基本思想。所以程序设计中&#xff0c;…

获取Items和Folder,以及Folder里面的Items,Folder里面的Folder 四种方法

获取Items: foreach (SPListItem item in list.Items){} 获取Folder: foreach (SPListItem folder in list.Folders){} 获取特定Folder的Items: SPQuery myquery new SPQuery(); myquery.Folder tempfolder; foreach (SPListItem tempitem in templist.GetItems(myquery)) {}…

asp.net控件开发基础十一

上一篇讨论了集合属性的使用,这一篇我们主要来讨论视图状态的自定义管理.刚开篇的时后在最后把属性值用视图状态来保存时,得以把当前状态保存下来,关于视图状态的概述,这里不再累赘,没了解过的朋友可以在MSDN里输入视图状态概述了解一下.以下我们还是以以前讲过的内容为例,一起…

编码风格(Coding Style)和编程准则(Programming Guidelines)

编码风格(Coding Style)和编程准则(Programming Guidelines) 一、编码风格 1、哑元 在类中没有定义该成员变量&#xff0c;但是在成员函数参数列表中出现&#xff0c;以区分其它重载函数的变量&#xff0c;称为哑元。 iterator(IntStack& is, bool) 2、继承接口 clas…

java代码的测试手段

##一、控制台打印输出 try{System.out.println("加载配置:"configuration.getClass());return configuration.buildSessionFactory();}catch(Exception e){System.out.println("配置异常"e.getMessage());return null;}##Junit Test Case单元测试 junit4学…