内联函数(Inline Functions)

内联函数(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++

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值