C++问题记录(1)


1. 模板函数定义在.h文件

对普通函数来说,声明放在头文件中,定义放在源文件中,其它的地方要使用该函数时,仅需要包含头文件即可,因为编译器编译时是以一个源文件作为单元编译的,当它遇到不在本文件中定义的函数时,若能够找到其声明,则会将此符号放在本编译单元的外部符号表中,链接的时候自然就可以找到该符号的定义了。

而对模板函数来说,首先明确,模板函数是在编译器遇到使用模板的代码时才将模板函数实例化的。 若将模板函数声明放在tem.h,模板定义放在tem.cpp,在main.cpp中包含头文件,调用add,按道理说应该实例化int add(int,int)函数,即生成add函数的相应代码,但是此时仅有声明,找不到定义,因此此时,它只会实例化函数的符号,并不会实例化函数的实现,即这个时候,在main.o编译单元内,它只是将add函数作为一个外部符号,这就是与普通函数的区别,对普通函数来说,此时的add函数已经由编译器生成相应的代码了,而对模板函数来说,此时并没有生成add函数对应的代码。此时编译main.cpp单元不会报错,但链接就会出现add函数未定义的错误。

原文链接


2. 类型别名

使用方法:

1
typedef 别名 原本类型名

C++11 中引入了新的定义方法,原来的也可以用

1
using 别名 = 原本类型名

类型别名在使用的时候不能简单理解为把类型别名替换成原本的样子

例如:

1
2
typedef char *pstring;
const pstring cstr = 0;

这里的cstr是指向char的常量指针,而不是指向char常量的指针。pstring是char指针,const 修饰pstring,是在修饰指针而不是常量。不能理解成const char* cstr=0.

  • string对象初始化C风格的char指针

    C++中的string字符串类来源于文件。

    C风格的字符串是以空格’\0’结尾的字符数组,可以直接用这种字符数组给string对象赋值,但反之不可以。为了解决这一问题,string中有一个成员函数c_str().使用如下:

    1
    2
    string str = "This is a test";
    const char* ch = str.c_str();
  • 预处理器追踪定义的几个调试变量

    1. _func_ : 当前运行的函数名
    2. _FILE_ : 存放文件名的字符串字面值
    3. _LINE_ : 存放当前行号的整性字面值
    4. _TIME_ : 存放文件编译时间的字符串字面值
    5. _DATE_ : 存放文件编译日期的字符攒字面值

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!