#ifndef #define #endif typedef typename
1.ifndef define endif
我们经常在c++的头文件中见到一堆#ifndef #define #endif这种标识。这些到底是用来干啥的?
在一个比较大的工程里,可能会出现一个头文件被多个文件同时include的情况。然后当这些文件编译链接成一个可执行文件的时候,会出现大量重复定义的错误。
比如我们打开stl库中vector源码,开头就有这么一个定义
#ifndef _LIBCPP_VECTOR
#define _LIBCPP_VECTOR
.......
然后文件最后定义
#endif // _LIBCPP_VECTOR
ifndef,意为if not define。意思是当文件编译到该行,如果该文件还没被编译过,那么程序将define _LIBCPP_VECTOR,并执行后面的代码。反之将不会再次编译文件。
endif出现在程序的最后,与ifndef或ifdef配对出现,作为结束的标识符。
2.typedef定义类型别名
typedef,很容易就能明白他的作用是type define。我们可以看看他的几个常见用法。
比如我们在stl源码中,经常看到这种类似的代码
public:typedef _Allocator allocator_type;typedef allocator_traits<allocator_type> __alloc_traits;typedef typename __alloc_traits::size_type size_type;
protected:typedef _Tp value_type;typedef value_type& reference;
上面的例子,就是为类别举个别名。比如将_Tp起个别名为value_type。这样做最大的好处就是可以非常简单明了的读懂变量的含义。
我们也可以自己举一个例子。
#include<iostream>
using namespace std;
typedef int Price;void func() {Price price = 10;cout<<"book's price is: "<<price<<endl;
}int main(int argc, char const *argv[])
{func();return 0;
}
这样在其他地方,我们就可以将Price代替int当做一种类型直接使用了,这样代码的可读性就得到了较大提高。
3.typedef定义平台类型
typedef定义平台类型也是我们在各种类库源码中常见的一种方式。
以size_t为例,_size_t.h头文件定义如下
#ifndef _SIZE_T
#define _SIZE_T
#include <machine/_types.h> /* __darwin_size_t */
typedef __darwin_size_t size_t;
#endif /* _SIZE_T */
可以看到size_t其实就是__darwin_size_t。
如果我们再查看__darwin_size_t
#if defined(__SIZE_TYPE__)
typedef __SIZE_TYPE__ __darwin_size_t; /* sizeof() */
#else
typedef unsigned long __darwin_size_t; /* sizeof() */
#endif
上面这段代码告诉我们,如果定义了__SIZE_TYPE__
类型,那么__darwin_size_t就是__SIZE_TYPE__
。如果没有,就将unsigned long定义为__darwin_size_t。
宏定义就是简单的字符串替换。与定义宏相比,typedef是定义了一种类型的新别名,而不是单纯的字符串替换,所以他比宏要来的稳妥。
4.typedef struct
typedef还可以与struct配合使用,为struct定义别名。
typedef struct Teacher {string name;int age;Teacher(string tname, int tage): name(tname), age(tage) {}
}tea;void func() {tea t1("lili", 26);cout<<"name is: "<<t1.name<<", age is: "<<t1.age<<endl;
}int main(int argc, char const *argv[])
{func();return 0;
}
输出结果:
name is: lili, age is: 26
上面的代码为Teacher结构体定义了别名tea,后面就可以直接使用tea。
如果struct前面没有typedef关键字,那么tea将会是一个变量而不是别名。具体可以看下面的代码
struct Teacher {string name;int age;
}tea;void func() {tea.name = "lili";tea.age = 26;cout<<"name is: "<<tea.name<<", age is: "<<tea.age<<endl;
}int main(int argc, char const *argv[])
{func();return 0;
}
此时代码的输出为
name is: lili, age is: 26
应该可以看出两者的区别
typedef typename
我们还经常看到typedef typename连在一起的用法,比如我们在vector的源码中,能看到大段这种定义:
typedef typename __base::__alloc_traits __alloc_traits;typedef typename __base::reference reference;typedef typename __base::const_reference const_reference;typedef typename __base::size_type size_type;typedef typename __base::difference_type difference_type;typedef typename __base::pointer pointer;typedef typename __base::const_pointer const_pointer;
上面为什么要加上typename的关键字?
主要是在类型实例化之前,编译器并不知道像__base::size_type 这种是什么东东,因为__base引用size_type,有三种可能情况:
1.size_type是__base的静态成员变量。
2.size_type是__base的静态函数。
3.size_type是__base的嵌套内部类。
我们通过typename关键字,就明确告诉编译器,size_type是第三种情况为嵌套内部类,而不是前面两种情况。
#ifndef #define #endif typedef typename相关推荐
- ifndef/define/endif——主要目的是防止头文件的重复包含和编译
原文:http://www.jb51.net/article/100939.htm 原文:https://blog.csdn.net/abc5382334/article/details/180527 ...
- c:#ifndef, #define, #endif 作用
#ifndef, #define, #endif 作用 #ifndef 它是if not define 的简写,是宏定义的一种,实际上确切的说,这应该是预处理功能三种(宏定义.文件包含.条件编译)中的 ...
- c/c++头文件中#ifndef/#define/#endif的用法
想必很多人都看过"头文件中用到的 #ifndef/#define/#endif 来防止该头文件被重复引用".但是是否能理解"被重复引用"是什么意思?头文件被重复 ...
- [Windows编程] #pragma once 和#ifndef ... #define ... #endif 比较
C++中防止头文件被多次include 的常见方式有: 1) 用#ifndef ... #define ... #endif 宏 #ifndef __MYHEADER_H__ #define __ ...
- C语言头文件为什么要加#ifndef #define #endif(防止头文件重复包含)
当你用VC的菜单新增一个类,你会发现自动生成的代码总是类似下面的样子: #if !defined(AFX_XXXX__INCLUDED_)#define AFX_XXXX__INCLUDED_具体代码 ...
- C++中#ifndef/#define/#endif使用详解
想必很多人都看过"头文件中的 #ifndef/#define/#endif 防止该头文件被重复引用".但是是否能理解"被重复引用"是什么意思?是不能在不同的两个 ...
- #ifndef/#define/#endif
#ifndef/#define/#endif 头文件中的 #ifndef/#define/#endif 防止该头文件被重复引用 "被重复引用"是指一个头文件在同一个cpp文件中被i ...
- 【转载】#pragma once与#ifndef #define #endif的区别
一.相同点 两者的共同点都是为了避免同一个文件被 include 多次,但是 #ifndef #define #endif 不只有这个作用. 在能够支持这两种方式的编译器上,二者并没 ...
- #ifndef.#define, #endif 的用法
文件中的#ifndef.#define, #endif 很关键,是为了避免多重包含,比如如果两个C文件同时包含同一头文件,那么就会出现问题,所以使用这种方法可以有效避免这种情况. 一般用法: 以add ...
- 每日一题(12)—— .h头文件中ifndef/define/endif的作用
.h头文件中ifndef/define/endif的作用? 分析: 防止头文件被重复包含. #ifndef _TEST_H_ #define _TEST_H_/* test.h */#endif / ...
最新文章
- CI框架 -- 附属类
- 英伟达验证图片加载不出来_让大卫雕塑跳舞、蒙娜丽莎说话,英伟达视频合成有如此多「骚操作」...
- linux systemd服务,systemd服务管理
- ML之sklearn:sklearn.metrics中常用的函数参数(比如confusion_matrix等 )解释及其用法说明之详细攻略
- java contains 通配符_java删除文件支持通配符
- 在Vs.net中集成 NDoc生成的 Html Help 2帮助文档
- 5_1 大理石在哪儿(UVa10474)排序与查找
- MSSQLServer基础07(事务,存储过程,分页的存储过程,触发器)
- Linux下查看CPU信息、机器型号等硬件信息命令
- 【转载】分层开发思想与小笼包
- 诺基亚在日本测试5G网络 网速可达256MB/s
- create user 'root'@'localhost' identified by 。。。
- Typecho中的gravatar头像无法加载
- 犀牛插件开发-插件兼容性-Rhino插件-什么是Rhino插件
- 004--MySql数据库的淘宝商城数据库设计
- mac android studio keymap,Android Studio keymap for Mac
- day16 Java 集合
- Alphafold2蛋白质三维结构预测AI工作站配置
- 马云 996 一文的诡辩与话术:大家是怎么被洗脑还帮人数钱的
- java ftp上传文件 linux_linux下用java实现ftp上传、下载文件