目录
摘要
1. 存储类型说明符(Storage Class Specifiers)
- auto
- register
- static
- extern
- mutable
2. 访问说明符(Access Specifiers)
- public
- protected
- private
3. 类型限定符(Type Qualifiers)
- const
- volatile
- restrict
4. 函数说明符(Function Specifiers)
- inline
- virtual
- explicit
5. 其他说明符
- friend
- typedef
- using
总结
摘要
在 C++ 中,specifiers(限定符或说明符)是用于修饰变量、函数、类等各种程序元素的关键字。常用的 specifiers 包括存储类型说明符、访问说明符、类型限定符等。我们将简单介绍有哪些常见的 specifiers,后续我会针对某些限定符再进行详细介绍,比如const,friend。
1. 存储类型说明符(Storage Class Specifiers)
存储类型说明符用于指定变量的存储方式和生存期。
- auto
`auto` 说明符用于让编译器自动推导变量的类型。
auto x = 5; // 编译器推导出 x 是 int 类型
auto y = 3.14; // 编译器推导出 y 是 double 类型
- register
建议编译器将变量存储在寄存器中,而不是 RAM 中(现代编译器可能会忽略这个)。
register int count = 0;
- static
a. 局部静态变量:函数内部的静态变量在函数调用之间保留其值。
b. 静态成员变量:类中的静态成员变量在所有对象之间共享。
void func() {static int counter = 0;counter++;std::cout << "Counter: " << counter << std::endl;
}class MyClass {
public:static int s_value;
};int MyClass::s_value = 0; // 定义静态成员变量
- extern
声明一个变量或函数在另一个文件中定义,提示编译器该变量或函数的定义在其他地方,比如另外的C++文件或C文件中。
extern int count;
void func();int main() {func();std::cout << count << std::endl;return 0;
}
- mutable
允许在 const 成员函数中修改成员变量。
class MyClass {
public:void setValue(int v) const {value = v;}
private:mutable int value;
};
2. 访问说明符(Access Specifiers)
访问说明符控制类成员的访问权限。
- public
公有成员可以被任何代码访问。
class MyClass {
public:int publicVar;
};
- protected
受保护成员可以被类及其子类访问。
class Base {
protected:int protectedVar;
};class Derived : public Base {
public:void setProtectedVar(int val) {protectedVar = val;}
};
- private
私有成员只能被类本身访问,不能被类的外部或其子类访问。
class MyClass {
private:int privateVar;
};
3. 类型限定符(Type Qualifiers)
类型限定符用于进一步限定变量的特性。
- const
表示变量的值不能被修改。
const int x = 10;
在函数中,`const` 可以用于成员函数,表示该函数不能修改对象的状态。
class MyClass {
public:void display() const {std::cout << value << std::endl;}
private:int value;
};
- volatile
提示编译器该变量可能被外部因素修改,编译器不要对该变量进行优化。
volatile int flag = 1;
- restrict
仅在 C99 中引入的指针限定符,提示编译器该指针是唯一访问其所指对象的指针,用于优化。
void updateValues(int *restrict ptr) {// 处理 ptr
}
4. 函数说明符(Function Specifiers)
函数说明符用于修饰函数的行为。
- inline
提示编译器将函数代码插入到每个调用点以减少函数调用开销。
inline void func() {std::cout << "Inline function" << std::endl;
}
- virtual
用于基类中声明虚函数,以便在派生类中进行重写。
class Base {
public:virtual void display() {std::cout << "Base class" << std::endl;}
};class Derived : public Base {
public:void display() override {std::cout << "Derived class" << std::endl;}
};
- explicit
用于构造函数或转换函数,防止隐式转换。
class MyClass {
public:explicit MyClass(int x) {// 构造函数}
};MyClass obj1 = 42; // 错误,不能隐式转换
MyClass obj2(42); // 正确,显式转换
5. 其他说明符
- friend
允许另一个类或函数访问类的私有和保护成员。
class MyClass {friend void display(const MyClass& obj);
private:int value;
};void display(const MyClass& obj) {std::cout << "Value: " << obj.value << std::endl;
}
- typedef
定义类型的别名。
typedef int Integer;
Integer x = 10;
- using
现代 C++ 中,用于定义类型的别名,通常代替 `typedef`。
using Integer = int;
Integer x = 10;
总结
1. 捕获变量的生命周期:在使用 `lambda` 捕获变量时,确保捕获的变量在 `lambda` 存在期间有效。
2. 虚函数和析构函数:如果类有虚函数,通常也应该声明虚析构函数,以确保正确的资源释放。
3. `const` 成员函数:确保成员函数不修改对象状态,以便在多线程环境中更安全地使用。
4. `mutable` 的使用:在 `const` 成员函数中修改成员变量时,慎用 `mutable`,确保其使用合理,否则很容易翻车。