这篇文章主要介绍“C++核心技术知识有哪些”,在日常操作中,相信很多人在C++核心技术知识有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++核心技术知识有哪些”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
创新互联建站主要从事网站设计制作、做网站、网页设计、企业做网站、公司建网站等业务。立足成都服务海伦,十载网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18980820575
1. 自动类型推导 auto & decltype()
关于类型可能很多同学会觉得这个话题比较简单,因为这基本是所有语言的基础,C/C++、Java等等这些静态类型语言...,基本都放在第一章节讲解,而且很多语言是相通的,但是C++有一个比较强大的关键字auto,我觉得有必要强调一下。其实,我们可以根据这个词的意思差不多猜出这个关键字的功能 —— 自动类型推导。也就是说如果一个变量的类型是auto时,它会根据变量的值自动推导出类型。那么,可能就会有朋友产生疑问了:变量是什么类型不是很容易看出来吗?感觉没什么用处。也许在C语言或Java中,确实,变量的类型清晰可见,但是C++就不一样了。例如,
templateauto add(T t, U u) { return t + u; }
C++中有模板的概念,代码中所示模板就是实现两个对象t和u的加法,当我们调用add函数时,由于使用了auto关键字,返回值类型会自动推导,即为t+u结果类型,如下:
auto b = add(2, 5); //这里的b是int型auto c = add(2.3, 8); //这里的c是float型
到这里,可能又有朋友说,这也没什么呀,我还是能一眼看出结果的类型,但是这里因为有了auto,才更加体现了C++模板的优势,定义一次函数,就可以进行多种类型数据的运算处理,并可以返回不同类型的结果,实现代码的复用。那么,除了这种比较简单的情况,还有没有比较复杂的类型?下面接着看:
vector> pred_boxes;for (auto pred_box = pred_boxes.begin(); pred_box != pred_boxes.end(); pred_box++){ pred_box->push_back(batch_id);}
这是我从caffe框架中截取的一段代码,先不管其含义,仅仅关注auto的用法。这里是实现一个遍历的功能,将batch_id存到pred_box中。我们定义了一个迭代器pred_box,这里由于auto会自动推导其类型,我们几乎什么都不用管。但是实际上它的类型是什么样的呢?请看:
vector>::iterator pred_box;
就是上面的代码中所写,是不是觉得繁琐了很多。说到遍历,我们也可以将上面的代码这样简化:
vector> pred_boxes;for (auto pred_box :pred_boxes){ pred_box->push_back(batch_id);}
世界又清净了一些!
说完auto,C++中还有一个与自动类型获取有关的关键字 —— decltype。
那么这二者有什么区别呢?auto关键字根据表达式的值推导其类型,可以假想为auto变成了这个类型(实际上不是)。在这个过程中表达式是会被计算的,但是有时候我们并不想表达式被计算,但是仍然希望得到表达式值的类型,这就用到了decltype,用法就是decltype(表达式),举个栗子:
decltype(pred_boxes) pred_boxes1;
我们定义一个和pred_boxes类型的相同的变量pred_boxes1
同样,对于下面的表达式:
int &k = 1;decltype(k) j = 1;
j的类型就是int引用类型了。
2. 常量限定符const与 constexpr
讲完了自动类型推导,接下来说一下C++中与常量定义相关的两个关键词 const 和 constexpr。
首先它们都是限定符,起到对变量进行限定的作用,当我们不希望一个变量的值被修改时,我们就需要用const进行限定。比如我们希望固定一个缓冲区的大小:
const int bufferSize = 1024;
那么,这里bufferSize便为不可修改变量,这里的用法与在C中一样,下面讲一下const在C++中的用法。
(1)const的用法
const与引用一起使用
在C++中const会经常与引用一起使用,如下:
const int i = 512;const int &j = i;
这里i与j都是常量,i是整型常量,就是整型引用常量(指向常量的引用),而且需要注意一点,const常量只能作为const常量的值(有点拗口!)
举个例子:
这里j是一个指向常量的引用,它也可以作为一个值,初始化另一个常量如下
const int &k = j;
这里k如果是一个引用的话必须为常量,如果不是引用的话,可是是一个变量。如下:
int k = j;
可能有的朋友会有些疑惑,既然
int &k = j;
不可以,为什么去掉&就可以了呢?简单解释一下,其实引用并不是一个实体对象,而是代表了一种绑定关系。
对于
int &k = j;
来说,其含义是将k绑定到j, 虽然k和j名字不同,但是在硬件上,它们占用同一块内存,既然j是常量,那么k必然是常量,而
int k = j;
就不一样了
const与指针一起使用
除了与引用在一起鬼混,const还常常喜欢与指针一起玩耍。这里先简单说一下引用和指针的区别,虽然很简单,但是我觉得还是有必要略讲一下。上面谈到引用其实并不是一个实体对象,即不像整型变量、结构体、枚举等等这些变量独自占据内存空间,引用表示了一种绑定关系,将一个别名绑定到一块内存空间(所以定义引用变量时必须要初始化)。但是指针就不同了,本质上,指针是一块存储内存地址的变量,它有一块内存空间存储地址信息。那么const与指针一起使用,又会发生什么有意思的事呢?一起来看几个例子:
const double pi = 3.14;const double *ptr = π
ptr是一个指向const double类型的指针,所以其值必须为const double类型的地址,这里只需要保证指针指向的值不变即可,至于ptr中存的值(地址)是可以改变的,也就是说这里的const限定了指针指向的内存存的值,即上面pi不可改变。
上面说过,指针本身也是一个实体对象,不像引用徒有虚名。所以有一个叫常量指针的(const pointer)家伙。既然叫常量指针,const限定的是指针本身,这就意味着指针中的值不可改变,举个例子:
double pi = 3.14;double * const ptr = π
ptr中的值在其生命周期中永远指向&pi, 此时pi可以随意改变,但是ptr中存的地址是固定的。
那么将这两者结合起来就可以得到
const double pi = 3.14;const double * const ptr = π
这样ptr无论指向的值还是其本身都是不可以改变的。
const与类的成员函数一起使用
const除了与“变量”一起使用外,在C++中还会与类的成员函数一起用。这个涉及到类与对象相关的知识,还有成员函数,成员变量,展开讲的话会比较多,后面与类和对象放一起说。
(2)constexpr的用法
上面我们讲了讲const的用法,下面就简单说下constexpr。constexpr作为限定词在含义上与const并不相同,constexpr是为了在初始化一个变量时,让编译器判断这个变量的值是否是一个常量或常量表达式,如果该变量用constexpr限定,但是初始化值并不是一个常量或者常量表达式,编译器便会报错,(因为我们在定义常量时并不确定右边的表达式是否是常量表达式),这样看来还是难于解释,下面就用几个例子解释一下:
constexpr int a = k +1;constexpr int b = newfun();
在这两个例子中,编译器在编译时会检查k+1和newfun()是否是常量表达式(函数),如果不是,上面的定义就不成立,编译会失败。
常量表达式一个重要的特点就是在编译阶段已经确定,下面这个就不是常量表达式:
const int b = newfunc();
因为,这里newfunc()在程序运行的时候才知道结果,在编译阶段因为没有用constexpr限定,编译器并不会检查newfunc()
前面我们说了指针和引用,这里constexpr也是可以和它们一起使用的,但是限制地比较严格。以下用指针举例:
const int *i = nullptr;constexpr int *i = nullptr;
第一个i表示指向int常量的指针
第二个表示指向int的常量指针
3. 空指针NULL与nullptr
下面说一下C++中的空指针。熟悉C的朋友对空指针非常熟悉,NULL。对,C++中仍然有这个关键字,不信可以看上面的关键字表。但是,在标准C++不建议使用NILL,因为NULL是整数0的宏定义。我们经常使用空指针来初始化一个指针变量,试想一下如果用一个整数作为指针变量的值,总是有些不妥,尽管编译器不会报错。所以C++11标准推荐我们使用nullptr,这个关键字本身就是代表空指针,更加合适,所以下次如果你们在C++中初始化一个指针变量时,就用名副其实的nullptr吧。
到此,关于“C++核心技术知识有哪些”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!