C++的常用关键字包括:auto、decltype、bool/false/true、throw、try、catch、class、consteval、constexpr、constinit、new、delete、const_cast、static_cast、dynamic_cast
、reinterpret_cast、explicit、export、friend、mutable、using、namespace、noexcept、
nullptr、operator、private、protected、public、static_assert、template、typename、this、thread_local、typeid、virtual等。我们结合代码示例来介绍各个关键字。
目录
auto根据变量初始化来推断变量类型。示例如下:
auto array = new int[8];
与auto不同的是,decltype是根据表达式来推断变量类型。语法格式如下:
decltype(expression) var;
表达式包括:变量、运算、函数等,示例如下:
- long add() {
- return 0;
- }
-
- void hello() {
- int a = 2;
- decltype(a) b; // b为int类型
- decltype(add()) c; // c为long类型
- }
bool关键字表示布尔变量,只有true或false两种变量值。
使用关键字throw抛出异常,使用try/catch来捕获异常。示例代码如下:
- try {
- std::string msg("This is a test exception");
- throw msg;
- } catch (const std::string &e) {
- printf("exception=%s", e.c_str());
- }
C++的类与java类相似,都是面向对象编程。类的声明示例如下:
- #include <string>
-
- class Person {
- private:
- int m_age;
- std::string m_name;
- public:
- void setAge(int age);
- int getAge();
- void setName(const std::string &name);
- std::string getName();
- };
对应的类实现如下:
- #include "Person.h"
-
- void Person::setAge(int age) {
- m_age = age;
- }
-
- int Person::getAge() {
- return m_age;
- }
-
- void Person::setName(const std::string &name) {
- m_name = name;
- }
-
- std::string Person::getName() {
- return m_name;
- }
创建Person类的对象实例:
- auto person = new Person();
- person->setAge(10);
- person->setName("frank");
- printf("name=%s, age=%d", person->getName().c_str(), person->getAge());
constexpr只能修饰带有return的函数。在C++20增加了consteval修饰常量表达式,不同的是,在编译期确定参数类型。示例如下:
- constexpr int hello(int a, int b) {
- return a + b;
- }
另外,函数体内不能有赋值运算,否则有如下报错:
subexpression not valid in a constant expression
在C++提供关键字new来创建对象,delete释放对象。在C语言是用库函数malloc来申请内存,free来释放内存。要注意的是,释放数组需要加上[]。示例如下:
- // 创建对象
- auto person = new Person();
- // 释放对象
- delete person;
- // 创建数组
- auto array = new int[8];
- // 释放数组
- delete[] array;
C++提供const_cast、static_cast、dynamic_cast和reinterpret_cast四种类型转换,如下表所示:
| const_cast | 用于修改const属性,接受指针或引用类型 |
| static_cast | 用于基本类型转换 |
| dynamic_cast | 用于有继承关系的类指针转换,支持类型检查 |
| reinterpret_cast | 用于指针类型转换 |
类型转换的示例代码如下:
- // const_cast用于const属性
- const int a = 10;
- int &b = const_cast<int &> (a);
- // static_cast基本类型转换
- float x = 10.5f;
- int y = static_cast<int> (x);
- // dynamic_cast用于子类与父类转换
- SuperMan *superman = new SuperMan();
- superman->setAge(100);
- Person *person = dynamic_cast<Person*> (superman);
- // reinterpret_cast用于指针类型转换
- void *data = (void *) "hello";
- char *new_data = reinterpret_cast<char *> (data);
explicit用于修饰单参数的构造函数,被修饰的构造函数只能被显式调用,不能被隐式调用。示例如下:
- class Person {
- private:
- int m_age;
- public:
- explicit Person(int age);
- };
C语言有extern关键字用于声明全局变量,但是C++的模板没法用extern修饰。因此,提供export修饰在头文件声明的模板类或模板函数,其他源文件只要引用该头文件即可使用模板类或模板函数。
friend关键字把函数声明为友元函数。声明函数为外部类的友元函数后,外部类可以通过友元函数访问该类的私有成员。示例代码如下:
- class Pointer;
-
- class Calculator {
- public:
- Pointer* add(Pointer &a, Pointer &b);
- };
-
- class Pointer {
- // 声明为Calculator的友元函数
- friend Pointer* Calculator::add(Pointer &a, Pointer &b);
- private:
- int m_x;
- int m_y;
- public:
- Pointer(int x, int y);
- };
-
- // Calculator访问Pointer的私有成员,通过对象访问
- Pointer* Calculator::add(Pointer &a, Pointer &b) {
- return new Pointer(a.m_x + b.m_x, a.m_y + b.m_y);
- }
mutable用于且只能修饰类的成员变量,与const修饰常量相反。比如,constexpr修饰的常量表达式不允许修改成员变量,而成员变量添加mutable修饰符后可修改。示例如下:
- class Person {
-
- private:
- mutable int m_age;
- public:
- explicit Person(int age);
- constexpr int getAge();
-
- };
-
- constexpr int Person::getAge() {
- m_age += 10; // 修改成员变量
- return m_age;
- }
非成员变量使用mutable修饰符会报错如下:
'mutable' can only be applied to member variable
命名空间用于模块隔离,避免模块之间命名冲突。示例代码如下:
- namespace Learning {
- class Person {
-
- private:
- std::string m_name;
- public:
- void setName(const std::string &name);
- std::string getName();
- };
- }
使用using引用命名空间,需要注意的是遵循最小原则。示例如下:
- // 直接命名空间引用
- Learning::Person *person1 = new Learning::Person();
- // 引入命名空间
- using namespace Learning;
- Person *person2 = new Person();
使用noexcept修饰函数禁止抛出异常,防止错误扩散。示例如下:
std::string getName() noexcept;
在C语言使用NULL表示空指针,java使用null表示空指针,Object-C使用nil表示空指针。当然,今天的主角是C++,它使用nullptr表示空指针。
与java类似,C++提供private、protected和public访问修饰符,可以修饰类、函数、变量。三者对比如下:
| private | 类内部访问 |
| proteted | 有继承关系的类可访问 |
| public | 类外部都可以访问 |