本文将对一些常见c++关键字做一个总结,简单的一笔带过,复杂的会有详细的使用示例。
目录
一、C++11新增关键字
1. constexpr
2. decltype
3. final
4. override
5. =delete
6. =default
二、传统关键字
1. asm
2. auto
3. bool
4. break
5. case
6. catch
7. char
8.class
9. const
10. const_cast用法:
11. continue
12. default
13. delete
14. do
15. double
16. dynamic_cast
17. else
18. enum
19. explicit
20. export
21. extern
22. false
23. float
24. for
25. friend
26. goto
27. if
28. inline
29. int
30. long
31. mutable
32. namespace
33. new
34. operator
35. private
36. protected
37. public
38.register
39. reinterpret_cast
40. return
41. short
42. signed
43. sizeof
44. static
45. static_cast
46. struct
47. switch
48. template
49. this
50. throw
51. true
52. try
53. typedef
54. typeid
55. typename
56. union
58. using
59. virtual
60. void
61. volatile
62. wchar_t
constexpr可以修饰函数参数、函数返回值、变量、类的构造函数、函数模板等,是一种比const更加严格的约束,它修饰的表达式除了具有“运行时常量性”,也具有“编译时常量性”,即constexpr修饰的表达式的值在编译期间可知。详细使用参考:《Effective Modern C++》学习笔记之条款十五:只要有可能使用constexpr,就使用它_王木木-CSDN博客
decltype的作用是,以一个普通表达式作为参数,返回该表达式的类型,主要用在那些返回值依赖于形参型别的函数模板场景。详细使用参考:《Effective Modern C++》学习笔记之条款三:理解decltype_王木木-CSDN博客
使用final
关键字修饰的类,表示这个类不能够被继承,否则将会编译报错。
#include
class A final{
};
// 编译报错,A不能被继承
class B : A {
};
在子类继承父类时,如果想要重写父类的虚函数,则可以在子类中重写的函数但后面使用override
关键字进行修饰,如果在子类的重写函数的签名写错,则会提示编译错误,避免一些低级错误出现。
include
class A {
public:
virtual void func1(){}
};
class B : A {
public:
// 编译报错,父类中的func1函数签名与该函数签名不一致,无法完成覆盖
virtual void func1(int i) override {}
};
当为了不让一个类被拷贝,有两个方法可以完成:
private
属性=delete
所以如果你不想让编译器自动生成默认的构造函数,则可以在构造函数后面加上=delete
,这样编译器就会删除对应的默认构造函数了。
#include
class CobjectA {
public:
CobjectA(int i) {};
CobjectA() = delete;
CobjectA(const CobjectA& c) = delete;
operator=(const CobjectA& c) = delete;
};
int main()
{
CobjectA Test; // 报错,默认构造函数被删除
CobjectA Test1(1);
CobjectA Test2 = Test1;// 报错,默认拷贝构造函数被删除
CobjectA Test3(3);
Test3 = Test1; // 报错,等号复制函数被删除
return 0;
}
详细使用说明,参考:《Effective Modern C++》学习笔记之条款十一:优先选用delete删除函数,而非private未定义函数_王木木-CSDN博客
在C++11中,如果在已经自定义构造函数时,仍然想要编译器为我们生成默认的构造函数,则只需要在构造函数的参数列表后面加上=default
关键字,此时,即使我们自定义了构造函数,但编译器依然为我们生成默认构造函数:
#include
class CobjectA {
public:
CobjectA(int i) {};
CobjectA() = default; // 提示编译器为该类生成默认构造函数
};
int main()
{
CobjectA Test; // 此时仍然可以调用默认构造函数
std::cout << "Test Con !" << std::endl;
return 0;
}
asm (指令字符串):允许在 C++ 程序中嵌入汇编代码。
auto C++98中表示自动变量,C++11中对其赋予新的特性,即修饰的变量类型自动推导,另外auto修饰的变量必须初始化。
int a = 10;
auto b = a; // b的类型同a为int
auto c = 10 / 3;// c的类型为float
auto d; //错误,auto变量必须初始化
bool(布尔)类型,C++ 中的基本数据结构,其值可选为 true(真)或者 false(假)
break(中断、跳出),用在switch语句或者循环语句中。程序遇到 break 后,即跳过该程序段,继续后面的语句执行。
用于 switch 语句中,用于判断不同的条件类型。
catch 和 try 语句一起用于异常处理。
char 字符类型,C++ 中的基本数据结构
class(类)是 C++ 面向对象设计的基础。使用 class 关键字声明一个类。
注意:在类成员函数中,const关键字不能与static关键字同时使用,因为static函数是类的静态成员函数,静态成员函数不含有this指针
参考博客:C++进阶(六) :C++的四种强制类型转换_王木木-CSDN博客
continue(继续)关键字用于循环结构。它使程序跳过代码段后部的部分,与 break 不同的是,它是"继续循环"之意,不是 break(跳出)。
default(默认、缺省),常用于 switch 语句,但也可以用于修饰类的默认构造函数,表示需要编译为我们生成默认构造函数。可以参考博客:C++进阶(二) : 构造函数与析构函数【详解】_王木木-CSDN博客
delete(删除)释放程序动态申请的内存空间。delete 后面通常是一个指针或者数组 [],且只能 delete 通过 new 关键字申请的指针,否则会发生段错误。
do-while是一类循环结构。与while循环不同,do-while循环保证至少要进入循环体一次。
double(双精度)类型,C++ 中的基本数据结构,以双精度形式存储一个浮点数。
参考博客:C++的四种强制类型转换
else 紧跟在 if 后面,用于对 if 不成立的情况的选择。
enum(枚举)类型,给出一系列固定的值,只能在这里面进行选择一个。
explicit(显式的)的作用是修饰类的构造函数以达到"禁止单参数构造函数"被用于自动型别转换目的
#include
using namespace std;
// 未使用explicit 修饰
class Point {
public:
int x, y;
Point(int x = 0, int y = 0)
: x(x), y(y) {}
};
// 使用explicit 修饰
class Point2 {
public:
int x, y;
explicit Point2(int x = 0, int y = 0)
: x(x), y(y) {}
};
void displayPoint(const Point& p)
{
cout << "(" << p.x << ","
<< p.y << ")" << endl;
}
void displayPoint2(const Point2& p)
{
cout << "(" << p.x << ","
<< p.y << ")" << endl;
}
int main()
{
// 自动类型推导,将数字1推导为Point实例,进行参数调用
displayPoint(1);
// 自动类型推导,将数字2推导为Point实例
Point p = 2;
// 编译报错,禁止单参数类型推导
displayPoint2(1);
}
为了访问其他编译单元(如另一代码文件)中的变量或对象,对普通类型(包括基本数据类、结构和类),可以利用关键字 extern,来使用这些变量或对象时;但是对模板类型,则必须在定义这些模板类对象和模板函数时,使用标准 C++ 新增加的关键字 export(导出)。
extern声明变量或函数为外部链接,提示编译器该变量或函数在其它文件中定义的。被其修饰的变量(外部变量)是全局变量或函数。
在 C++ 中,还可用来指定使用另一语言进行链接,这时需要与特定的转换符一起使用。目前仅支持 C 转换标记,来支持 C 编译器链接。使用这种情况有两种形式:
extern "C" 声明语句 extern "C" { 声明语句块 }
false(假的),C++ 的基本数据结构 bool 类型的值之一。等同于 int 的 0 值。
float(浮点数),C++ 中的基本数据结构,精度小于 double。
for 是 C++ 中的循环结构之一。
friend(友元)声明友元关系。友元可以访问与其有 friend 关系的类中的 private/protected 成员,通过友元直接访问类中的 private/protected 成员的主要目的是提高效率。友元包括友元函数和友元类。
goto(转到),用于无条件跳转到某一标号处开始执行,目前建议不再使用。
if(如果),C++ 中的条件语句之一,可以根据后面的 bool 类型的值选择进入一个分支执行。
inline(内联)函数的定义将在编译时在调用处展开。inline定义的内联函数,函数代码被放入符号表中 ,效率会很高,但是inline 函数要求短小,且没有耗时操作。
int(整型,integer),C++ 中的基本数据结构,用于表示整数,精度小于 long。
long(长整型,long integer),C++ 中的基本数据结构,用于表示长整数。
如果一个类的成员函数被声明为 const 类型,表示在该函数内不可更改该类的成员变量,也就是该函数不会修改类的非静态数据成员。但是有些时候需要在该类函数中对类的数据成员进行赋值,这个时候就需要用到 mutable 关键字,被mutable修饰的变量可以在const函数内被修改:
class ClxTest
{
public :
ClxTest();
~ ClxTest();
int GetOutputTimes() const {
// 因为m_iTimes被mutable修饰,所以,即使在const函数中依然可以修改其值
m_iTimes = 2;
}
private :
mutable int m_iTimes;
};
另外,在 Lambda 表达式的设计中,当外部变量被按值捕获(Caputre by Value)的方式捕获时,是不允许程序员在 Lambda 函数的函数体中修改该变量的。而以 mutable
修饰 Lambda 函数,则可以打破这种限制。
int x{0};
auto f1 = [=]() mutable {x = 42;}; // okay, 创建了一个函数类型的实例
auto f2 = [=]() {x = 42;}; // error, 不允许修改按值捕获的外部变量的值
namespace(命名空间)用于在逻辑上组织类,是一种比类大的结构。
new(新建)用于新建一个对象。若创建失败,一般场景下会跑出异常,但如果使用std::nothrow修饰,则不会跑出异常,只会返回nullptr:
int* p = new (std::nothrow) int;
operator(操作符)用于操作符重载。这是 C++ 中的一种特殊的函数。
private(私有的),C++ 中的访问控制符。被标明为 private 的字段只能在本类以及友元中访问。详细使用教程请参考博客:C++进阶(六) : 封装【详解】
protected(受保护的),C++ 中的访问控制符。被标明为 protected 的字段只能在本类以及其继承类和友元中访问。 详细使用教程请参考博客:C++进阶(六) : 封装【详解】
public(公有的),C++ 中的访问控制符。被标明为 public 的字段可以在任何类。 详细使用教程请参考博客:C++进阶(六) : 封装【详解】
请求编译器尽可能将register修改但变量放到寄存器中,以提升效率,但register使用需要注意以下几点:
参考博客:C++的四种强制类型转换
return(返回)用于在函数中返回值。程序在执行到 return 语句后立即返回,return 后面的语句无法执行到。
short(短整型,short integer),C++ 中的基本数据结构,用于表示整数,精度小于 int。
signed(有符号),表明该类型是有符号数,和 unsigned 相反。数字类型(整型和浮点型)都可以用 signed 修饰。但默认就是 signed,所以一般不会显式使用。
由于 C++ 每种类型的大小都是由编译器自行决定的,为了增加可移植性,可以用 sizeof 运算符获得该数据类型占用的字节数。
static 修饰不同类型变量会有不一样的属性:
参考博客:C++的四种强制类型转换
struct(结构)类型,类似于 class 关键字,与 C 语言兼容(class 关键字是不与 C 语言兼容的),可以实现面向对象程序设计,默认其成员为public。
switch(转换)类似于 if-else-if 语句,是一种多分枝语句。它提供了一种简洁的书写,并且能够生成效率更好的代码。但是,switch 后面的判断只能是int(char也可以,但char本质上也是一种int类型)。switch 语句最后的 default 分支是可选的。
template(模板),C++ 中泛型机制的实现。
this 返回调用者本身的指针。
throw(抛出)用于实现 C++ 的异常处理机制,可以通过 throw 关键字"抛出"一个异常。
true(真的),C++ 的基本数据结构 bool 类型的值之一。等同于 int 的非 0 值。
try(尝试)用于实现 C++ 的异常处理机制。可以在 try 中调用可能抛出异常的函数,然后在 try 后面的 catch 中捕获并进行处理。
typedef(类型定义,type define),其格式为:
typedef 类型 定义名;
类型说明定义了一个数据类型的新名字而不是定义一种新的数据类型。定义名表示这个类型的新名字。
指出指针或引用指向的对象的实际派生类型。
typename(类型名字)关键字告诉编译器把一个特殊的名字解释成一个类型。在下列情况下必须对一个 name 使用 typename 关键字:
union(联合),类似于 enum。不同的是 enum 实质上是 int 类型的,而 union 可以用于所有类型,并且其占用空间是随着实际类型大小变化的。
57. unsigned
unsigned(无符号),表明该类型是无符号数,和 signed 相反。
表明使用 namespace。
virtual(虚的),C++ 中用来实现多态机制。
void(空的),可以作为函数返回值,表明不返回任何数据;可以作为参数,表明没有参数传入(C++中不是必须的);可以作为指针使用。
volatile(不稳定的)声明一个变量是易变的,所以每次读取都会去内存中重新读取该值,而不是取相应的寄存器值,同样,他的性能会有所下降。声明时的语法如下:
int volatile nVint;
wchar_t 是宽字符类型,每个 wchar_t 类型占 2 个字节,16 位宽。汉字的表示就要用到 wchar_t。