
C++ keywords are language-reservedspecial wordsthat cannot be used as variable names, function names, etc. They control the behavior, types, and flow of programs.
1. Basic Data Types (Most Commonly Used)
| Keyword | Meaning (for Beginners) | Example / Description | Notes |
|---|---|---|---|
| bool | Boolean type, only true / false | bool ok = true; |
Core of conditional judgment |
| char | Single character (usually 1 byte) | char c = 'A'; |
Use single quotes |
| wchar_t | Wide character (often used to support Chinese, etc.) | wchar_t wc = L'中'; |
2 or 4 bytes, platform-dependent |
| char8_t | UTF-8 character (new in C++20) | char8_t c8 = u8'好'; |
Modern Unicode programming |
| char16_t | UTF-16 character (C++11) | ||
| char32_t | UTF-32 character (C++11) | ||
| int | Integer (usually 4 bytes) | int age = 18; |
Most commonly used integer type |
| short | Short integer (usually 2 bytes) | short s = 1000; |
Use when saving space |
| long | Long integer (at least 4 bytes, commonly 8 bytes) | long l = 1234567890L; |
Add L suffix |
| long long | Longer integer (at least 8 bytes, formalized in C++11) | long long big = 1LL<<60; |
Handle large numbers |
| float | Single-precision floating-point number | float f = 3.14f; |
Add f suffix |
| double | Double-precision floating-point number (default floating-point type) | double pi = 3.1415926535; |
Higher precision |
| void | No type (functions returning no value, generic pointers, etc.) | void func(); |
Commonly used in function declarations |
| unsigned | Unsigned (combined with int/long, etc.) | unsigned int id = 4000000000u; |
Larger range, but cannot represent negative numbers |
2. Variable/Object Lifetime and Storage (Storage & Duration)
| Keyword | Meaning (for Beginners) | Example / Common Usage | Modern Recommendation |
|---|---|---|---|
| auto | Let the compiler automatically deduce the type (the most important usage after C++11) | auto x = 3.14; → double |
Highly recommendedmost commonly used when writing code |
| const | Constant, cannot be modified | const int MAX = 100; |
Safer than #define, has type checking |
| static | Static storage (shared within a file, shared among class members, retains value within a function) | static int count = 0; |
Static class members need initialization outside the class |
| extern | Declare variables/functions defined elsewhere (cross-file use) | extern int globalVar; |
Commonly used in multi-file projects |
| thread_local | Each thread has its own copy (C++11) | Multithreaded programming | |
| register | Suggested to place in a register (modern compilers basically ignore this) | Basically not used, outdated | |
| mutable | Allows a const member function to modify this member | Special scenario inside a class |
3. Classes and Core Object-Oriented Programming (OOP Basics)
| Keyword | Meaning (for Beginners) | Example / Description | Importance |
|---|---|---|---|
| class | Define a class (private by default) | class Student { ... }; |
★★★★★ |
| struct | Define a struct (public by default, compatible with C) | struct Point { int x,y; }; |
★★★★ |
| public | Public members, anyone can access | ||
| private | Private members, only this class and friends can access | ||
| protected | Protected members, accessible by this class + derived classes + friends | ||
| this | Pointer to the current object | this->age = 18; |
Often used to distinguish parameters with the same name |
| friend | Friend (allows access to private/protected) | friend class Utils; |
Rarely used; use with caution as it breaks encapsulation |
| virtual | Virtual function (implements polymorphism) | virtual void draw() = 0; |
Core of polymorphism |
| override | Explicitly declare this is an override (C++11, recommended to add) | void draw() override; |
Prevents spelling mistakes |
| final | Prohibit inheritance / prohibit overriding (C++11) | class My final {} |
Clear design intent |
| explicit | Prohibit implicit conversion (most common with single-argument constructors) | explicit MyClass(int x); |
Prevents accidental conversions |
4. Memory Management and Pointers
| Keyword | Meaning (for Beginners) | Example / Description | Modern Recommendation |
|---|---|---|---|
| new | Dynamically allocate memory (returns a pointer) | int* p = new int(5); |
Try to use smart pointers |
| delete | Free memory allocated by new | delete p; delete[] arr; |
Use in pairs to avoid memory leaks |
| nullptr | Null pointer constant (C++11, recommended replacement for NULL) | int* ptr = nullptr; |
Highly recommended |
5. Type Casting (4 casts, decreasing safety)
| Keyword | Meaning (for Beginners) | Safety | Recommended Use Cases |
|---|---|---|---|
| static_cast | Compile-time conversion (related types, numeric conversions, etc.) | High | Most commonly used in daily work |
| const_cast | Add/remove const or volatile | Medium | Rarely used, dangerous |
| dynamic_cast | Runtime-safe downcasting (polymorphic classes) | High | Type checking in inheritance hierarchies |
| reinterpret_cast | Low-level, dangerous bit-pattern reinterpretation (arbitrary conversion between pointers) | Low | Rarely used (e.g., hardware interaction) |
6. Control Flow (Most Basic)
| Keyword | Meaning (for Beginners) | Example |
|---|---|---|
| if / else | Conditional judgment (execute if the condition is satisfied, otherwise execute another part) | int a = 8; if (a > 10) { cout << "大于10"; } else { cout << "不大于10"; } |
| switch | Multi-branch selection (only supports integer/enum/char types) | int score = 9; switch (score) { case 9: cout << "优秀"; break; default: cout << "普通"; } |
| case / default | Branch labels in switch (case matches a value, default matches all unmatched cases) | char ch = 'a'; switch (ch) { case 'a': cout << "字母A"; break; default: cout << "其他字符"; } |
| for | Counting/range loop (suitable for scenarios with a known number of iterations) | for (int i=0; i<10; i++) { cout << i; }(counting loop)vector<int> v={1,2,3}; for (int num : v) { cout << num; }(range loop) |
| while | Check first, then execute (unknown number of iterations; loop only while the condition holds) | int i=1; while (i<=5) { cout << i; i++; } |
| do | Execute at least once, then check (unknown number of iterations; ensures first execution) | int i=1; do { cout << i; i++; } while (i<=5); |
| break | Break out of the current loop/switch branch (terminates immediately, does not execute subsequent content) | for (int i=0; i<10; i++) { if (i==5) break; cout << i; }(break out of the loop)switch (score) { case 9: break; }(break out of the switch branch) |
| continue | Skip the remaining part of the current loop iteration and go directly to the next iteration | for (int i=0; i<10; i++) { if (i%2==0) continue; cout << i; }(print odd numbers only) |
| return | Return the function result (for functions with a return value) or end a void function early | int add(int a, int b) { return a + b; }(return the function result)void print() { if (1) return; cout << "此行不会执行"; }(end a void function early) |
7. Exception Handling (Still common in modern C++, but not the first choice)
try / catch / throw
8. Templates and Modern Generic Programming (Intermediate/Advanced)
template、typename、concept(C++20)、requires(C++20)
9. Other Important but Less Frequently Used Keywords
- constexpr(C++11): compile-time constants/functions
- inlineSuggests function inlining (often used in header file definitions in modern C++)
- enumEnumeration (modern recommendation: enum class)
- namespace / usingNamespace management
- sizeofGet the byte size of a type/object
- typeidRuntime type information (rarely used)
- asmInline assembly (rarely used)
- gotoJump (strongly not recommended, breaks structure)
- exportTemplate export before C++20 (basically useless now)
Examples
1. auto (Automatic Type Deduction)
Let the compiler write the type for you, making the code more concise and less error-prone.
Examples
#include <vector>
#include <string>
int main() {
auto a = 42; // deduced to int
auto b = 3.14; // Deduced as double
auto c = "hello"; // Deduced as const char*
auto d = std::string("world"); // Deduced as std::string
auto vec = std::vector{1, 2, 3}; // Deduced as std::vector<int>
std::cout << a << " " << b << " " << c << " " << d << "\n";
for (auto x : vec) { // auto is commonly used in range-based for loops
std::cout << x << " ";
}
std::cout << "\n";
}
Output:
42 3.14 hello world 1 2 3
2. const (Constant)
Protect variables from accidental modification, write safer code.
Examples
int main() {
const int MAX = 100; // Must be initialized, cannot be changed
// MAX = 200; // Error! Cannot be modified
const double PI = 3.14159;
std::cout << "π ≈ " << PI << "\n";
int x = 10;
const int* p = &x; // The content pointed to by the pointer cannot be changed
// *p = 20; // Error!
x = 30; // But x itself can be changed
std::cout << *p << "\n";
}
圆周率 ≈ 3.14159 30
3. static (Static)
Make variables "live longer", commonly used for counting and sharing data.
Examples
void counter() {
static int count = 0; // Initialized only once, not destroyed when the function ends
count++;
std::cout << "Call " << count << " time"\n";
}
int main() {
counter(); // 1
counter(); // 2
counter(); // 3
}
Output:
第 1 次调用 第 2 次调用 第 3 次调用
4. nullptr (Modern Null Pointer)
Safer and clearer than NULL, avoiding type confusion.
Examples
int main() {
int* p1 = NULL; // Old-style (not recommended)
int* p2 = nullptr; // Modern C++ recommended approach
if (p2 == nullptr) {
std::cout << "p2 is a null pointer\n";
}
// nullptr can only be assigned to pointers, not to integers
// int x = nullptr; // Error!
}
Output:
p2 是空指针
5. range-based for (for(auto : ) range-for loop)
The simplest and safest way to iterate over containers.
Examples
#include <vector>
int main() {
std::vector<int> scores {85, 92, 78, 95};
// Traditional approach
for (size_t i = 0; i < scores.size(); ++i) {
std::cout << scores[i] << " ";
}
std::cout << "\n";
// Modern approach (recommended)
for (auto score : scores) {
std::cout << score << " ";
}
std::cout << "\n";
// If you need to modify elements, use a reference
for (auto& score : scores) {
score += 5;
}
for (auto score : scores) {
std::cout << score << " ";
}
}
Output:
85 92 78 95 85 92 78 95 90 97 83 100
6. explicit (Prohibit Implicit Conversion)
Prevents bugs caused by accidental type conversions; adding explicit is more rigorous.
Examples
class Distance {
private:
double meters;
public:
// explicit Distance(double m) : meters(m) {} // Adding explicit is safer
Distance(double m) : meters(m) {} // Without it, implicit conversion occurs
double get() const { return meters; }
};
void print(double d) {
std::cout << "Distance: " << d << " meters\n";
}
int main() {
Distance d = 500; // If the constructor is not explicit, this is allowed
print(d); // Implicitly converts Distance → double
// print(500); // If explicit is added, this line will error
}
Output (without explicit):
距离: 500 米
7. override (Explicitly Override Virtual Functions)
Writing override lets the compiler check whether you actually overrode a virtual function.
Examples
class Animal {
public:
virtual void speak() const {
std::cout << "Some animal sound\n";
}
};
class Dog : public Animal {
public:
void speak() const override { // Adding override is safest
std::cout << "Woof woof woof!\n";
}
};
int main() {
Animal* pet = new Dog();
pet->speak();
delete pet;
}
Output:
Woof woof woof!
8. constexpr (Compile-time Computation)
Complete calculations at compile time, making programs faster and safer.
Examples
constexpr int factorial(int n) {
return (n <= 1) ? 1 : n * factorial(n - 1);
}
int main() {
constexpr int f5 = factorial(5); // Computed as 120 at compile time
std::cout << "5! = " << f5 << "\n";
int x = 6;
// constexpr int f6 = factorial(x); // Error! x is not a constant
std::cout << "6! = " << factorial(x) << "\n"; // Runtime computation also works
}
Output:
5! = 120 6! = 720
9. using (Namespace + Type Alias)
using simplifies namespaces and creates readable type aliases.
Examples
#include <vector>
// Traditional typedef
typedef std::vector<int> IntVec;
// Modern using (more flexible, can be templated)
using StringVec = std::vector<std::string>;
int main() {
using std::cout; // Import only cout
using std::endl;
IntVec v1 {1, 2, 3};
StringVec v2 {"Apple", "Banana"};
cout << v1.size() << " " << v2.size() << endl;
}
Output:
3 2
10. enum class (Strongly-typed Enumeration)
Safer than plain enum, won't accidentally mix with integers.
Examples
enum class Color { Red, Green, Blue }; // Strongly typed, won't implicitly convert to int
int main() {
Color c = Color::Green;
// if (c == 1) {} // Error! Cannot compare directly with int
if (c == Color::Green) {
std::cout << "is green\n";
}
// Must explicitly convert to int
std::cout << "Underlying value: " << static_cast<int>(c) << "\n";
}
Output:
是绿色 底层值: 1