C++Primer笔记(1)

时间:2023-03-09 14:42:08
C++Primer笔记(1)

1.初始化

在C++中,初始化与赋值操作是完全不同的两个操作。初始化不是赋值,初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象的当前值擦除,而以一个新值来代替。

初始化的方式有:

 int test = ;
int test = {};
int test{};
int test();

第3行这种使用花括号初始化的方式被称为列表初始化(C++11新标准)。而从第2行中可以看出,赋值操作也可以采用一组由花括号括起来的初始值来完成。而采用这种初始化的方式的好处在于,在出现初始化操作存在丢失信息的风险时,编译器会进行警告,而另外两个却不会。当然,这必须是在初始化内置类型变量的情况下。

而所谓的丢失信息,譬如将一个占8字节类型的变量赋值给一个占4字节类型的变量时就会存在此类风险。

如果定义变量时没有指定初始值,则变量被默认初始化。堆中的内置变量被初始化为0,栈中的内置变量不被初始化、即其值未定义。类的对象未初始化,则其值由类确定。

类的值其实等同于类内各个成员的值,则上句话的意思就是,如果类的对象没有被初始化,则让编译器去类的定义中看看有没有提供类内初始值(C++新标准),有就照办,没有就别管。

2.引用

引用实质就是为对象起了一个别名而已。引用必须初始化!

int test1 = ;
int &test2 = test1;

此时对test2操作就等同于对test1操作。引用只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑定在一起。而且,引用的类型必须与其所引用的对象的类型一致,但是有两种例外:

第一种情况是在初始化常量引用时允许将结果能转换成引用类型的任意表达式作为初始值。

第二种情况是派生类引用向基类引用的自动类型转换。

3.const限定符

默认情况下,const对象仅在文件中有效。而想要实现只在一个文件中定义const对象,在其他多个文件中声明使用它,则需要该对象声明与定义都添加extern关键字。顶层const、底层const不过就是指针常量和常量指针。

4.constexpr和常量表达式

常量表达式是指值不会改变并且在编译过程就能得到计算结果的表达式。

将你认为是常量表达式的变量声明为constexpr类型(C++11新标准),以便由编译器检查变量的值是否是常量表达式。声明的constexpr变量一定是一个常量,而且必须使用常量表达式初始化。值得注意的是: 定义一个constexpr类型的指针,限定符constexpr只对指针有效,与指针所指对象无关!

 const int *p = nullptr; //p是一个指向整型常量的指针
constexpr int *q = nullptr; //q是一个指向整型的常量指针

5.类型别名

typedef与C语言一致。

C++有一种新的方法,别名声明。使用关键字using。

using pstring = char *;

其他特性与typedef一致。

值得注意的是类型别名不能像宏定义一样去直接替换理解,而应该将新生成的别名当做是一个新类型去理解。

 using pstring = char *;
const pstring ps1 = nullptr; //指向char的常量指针
const char *ps2 = nullptr; //指向const char的指针

显而易见,2、3行表达意义不同。

6.auto类型说明符

auto类型说明符(C++11新标准)能让编译器通过初始值来推算出变量的类型。显然,auto类型的变量必须有初始值。

int  test = ;
auto index = test; //index为int类型变量

要注意的是当使用auto在一条语句中声明多个变量时,所有变量的初始基本数据类型必须一致,因为一条语句中只能有一个基本数据类型。

7.decltype类型指示符

decltype类型指示符(C++11新标准)可以返回操作数的类型(包括引用及顶层const)。

const int test1 = ;
const int& test2 = test1;
decltype(test1) x = ; //x类型为const int
decltype(test2) x = test1; //x类型为const int&

要注意的有两点:

第一点,如果表达式内容是解引用操作,则decltype将得到引用类型。

第二点,如果给操作变量加上一层或多层括号,则decltypr将得到引用类型。

8.编写自己的头文件

类通常被定义在头文件中,所在头文件名字与类名一致。

为了防止头文件被重复包含,采用预处理功能头文件保护符来进行规避。

man.h

 #ifndef MAN_H
#define MAN_H
#include <string>
class man {
std::string name;
unsigned int age;
};
#endif