C++作为一门多范式编程语言,其核心优势在于既保留了C语言的高效性,又引入了现代编程语言的便利特性。从技术架构来看,C++主要包含三大核心组成部分:
在实际工程应用中,C++的独特价值体现在:
提示:虽然C++学习曲线较陡峭,但掌握后能深入理解计算机系统工作原理,这是其他高级语言难以提供的认知深度。
Visual Studio完整版方案
bash复制1. 访问官网下载Visual Studio Installer
2. 选择"使用C++的桌面开发"工作负载
3. 勾选以下可选组件:
- Windows 10/11 SDK
- C++ CMake工具
- 测试工具
4. 安装完成后创建新项目:
[文件] → [新建] → [项目] → [C++控制台应用]
VS Code轻量级方案
bash复制1. 安装MinGW-w64编译器(推荐版本8.1.0)
2. 配置系统环境变量PATH添加MinGW的bin目录
3. VS Code安装扩展:
- C/C++ (Microsoft)
- Code Runner
4. 创建tasks.json配置编译任务:
{
"version": "2.0.0",
"tasks": [{
"label": "build",
"type": "shell",
"command": "g++",
"args": ["-g", "${file}", "-o", "${fileDirname}\\${fileBasenameNoExtension}.exe"]
}]
}
对于Ubuntu/Debian系统:
bash复制# 安装完整开发工具链
sudo apt update
sudo apt install build-essential gdb cmake
# 验证安装
g++ --version
make --version
对于需要多版本GCC的场景,可使用update-alternatives管理:
bash复制sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 90 \
--slave /usr/bin/g++ g++ /usr/bin/g++-9
sudo update-alternatives --config gcc
code复制project/
├── include/ # 头文件
├── src/ # 源文件
├── lib/ # 第三方库
├── build/ # 构建目录
├── CMakeLists.txt # 构建配置
└── README.md
cmake复制cmake_minimum_required(VERSION 3.10)
project(HelloWorld)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(hello src/main.cpp)
C++的IO流基于继承体系实现:
code复制ios_base
├── ios
├── istream
| ├── ifstream
| └── iostream
└── ostream
├── ofstream
└── iostream
标准输入输出对象:
cin:istream实例,绑定到标准输入cout:ostream实例,绑定到标准输出cerr:无缓冲的错误输出clog:带缓冲的错误输出cpp复制#include <iomanip>
double pi = 3.141592653589793;
// 设置固定小数位
cout << fixed << setprecision(2) << pi; // 输出3.14
// 设置输出宽度
cout << setw(10) << left << "Hello"; // 左对齐占10字符
// 进制转换
cout << hex << 255; // 输出ff
cout << oct << 8; // 输出10
auto关键字原理
cpp复制auto x = 42; // int
auto y = 3.14; // double
auto z = "hello"; // const char*
// 引用类型推导
int val = 10;
auto& ref = val; // int&
decltype类型查询
cpp复制int x = 5;
decltype(x) y = 10; // y的类型与x相同(int)
// 与auto结合使用
decltype(auto) z = y; // 保留引用等修饰符
C++11引入的统一初始化语法:
cpp复制// 基础类型
int a{10};
double b{3.14};
// 数组
int arr[]{1, 2, 3};
// 类对象
class MyClass {
int x;
double y;
public:
MyClass(int a, double b) : x(a), y(b) {}
};
MyClass obj{10, 3.14};
// 容器
vector<int> vec{1, 2, 3};
注意:列表初始化会进行窄化检查,以下代码将产生编译错误
cpp复制int x{3.14}; // 错误:从double到int的窄化转换
code复制预处理 → 编译 → 汇编 → 链接
典型编译命令分解:
bash复制# 预处理(生成.i文件)
g++ -E main.cpp -o main.i
# 编译(生成.s汇编文件)
g++ -S main.i -o main.s
# 汇编(生成.o目标文件)
g++ -c main.s -o main.o
# 链接(生成可执行文件)
g++ main.o -o program
优化级别:
bash复制-O0 # 无优化(调试默认)
-O1 # 基本优化
-O2 # 推荐优化级别
-O3 # 激进优化
-Os # 优化代码大小
调试信息:
bash复制-g # 生成调试符号
-ggdb # 生成GDB专用格式
-g3 # 包含宏定义信息
警告控制:
bash复制-Wall # 开启所有警告
-Wextra # 额外警告
-Werror # 将警告视为错误
-pedantic # 严格符合标准
启动调试:
bash复制g++ -g main.cpp -o program
gdb ./program
核心命令:
code复制break <location> # 设置断点
run [args] # 启动程序
next/n # 单步跳过
step/s # 单步进入
print/p <expr> # 打印表达式
backtrace/bt # 查看调用栈
frame <n> # 选择栈帧
watch <var> # 设置监视点
continue/c # 继续执行
Valgrind内存检查:
bash复制valgrind --leak-check=full ./program
常用选项:
code复制--tool=memcheck # 内存检查(默认)
--track-origins=yes # 显示未初始化值的来源
--show-leak-kinds=all # 显示所有内存泄漏类型
示例头文件guard:
cpp复制#ifndef MYLIB_MYCLASS_H
#define MYLIB_MYCLASS_H
namespace mylib {
class MyClass {
public:
explicit MyClass(int value);
void doSomething();
private:
int m_value;
};
}
#endif // MYLIB_MYCLASS_H
cpp复制// myclass.h
#pragma once
class MyClass {
public:
void publicMethod();
private:
void privateMethod();
};
// myclass.cpp
#include "myclass.h"
void MyClass::publicMethod() {
// 实现代码
}
void MyClass::privateMethod() {
// 实现代码
}
多目录项目结构:
code复制project/
├── CMakeLists.txt
├── include/
│ └── mylib.h
├── src/
│ ├── mylib.cpp
│ └── main.cpp
└── tests/
└── test_mylib.cpp
对应CMake配置:
cmake复制cmake_minimum_required(VERSION 3.10)
project(MyProject)
# 设置包含目录
include_directories(include)
# 添加库目标
add_library(mylib STATIC src/mylib.cpp)
# 添加可执行文件
add_executable(main src/main.cpp)
target_link_libraries(main mylib)
# 添加测试
enable_testing()
add_executable(test_mylib tests/test_mylib.cpp)
target_link_libraries(test_mylib mylib)
add_test(NAME mylib_test COMMAND test_mylib)
使用vcpkg管理第三方库:
bash复制# 安装vcpkg
git clone https://github.com/microsoft/vcpkg
./vcpkg/bootstrap-vcpkg.sh
# 安装库
./vcpkg/vcpkg install fmt boost
# CMake集成
cmake -DCMAKE_TOOLCHAIN_FILE=./vcpkg/scripts/buildsystems/vcpkg.cmake ..
cpp复制// 优化前
for (int i = 0; i < 4; ++i) {
arr[i] = i * 2;
}
// 手动优化后(模拟循环展开)
arr[0] = 0;
arr[1] = 2;
arr[2] = 4;
arr[3] = 6;
注意:现代编译器在-O2及以上优化级别会自动进行循环展开,手动优化可能适得其反
行优先访问示例:
cpp复制// 好的访问模式(连续内存访问)
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLS; ++j) {
matrix[i][j] = 0;
}
}
// 差的访问模式(跳跃访问)
for (int j = 0; j < COLS; ++j) {
for (int i = 0; i < ROWS; ++i) {
matrix[i][j] = 0;
}
}
cpp复制#include <xmmintrin.h>
void prefetch_example(float* data, size_t size) {
for (size_t i = 0; i < size; ++i) {
_mm_prefetch((const char*)(data + i + 16), _MM_HINT_T0);
// 处理当前数据
process(data[i]);
}
}
文件处理示例:
cpp复制class FileHandle {
public:
explicit FileHandle(const char* filename)
: handle(fopen(filename, "r")) {
if (!handle) throw std::runtime_error("File open failed");
}
~FileHandle() {
if (handle) fclose(handle);
}
// 禁用拷贝
FileHandle(const FileHandle&) = delete;
FileHandle& operator=(const FileHandle&) = delete;
// 支持移动
FileHandle(FileHandle&& other) noexcept
: handle(other.handle) {
other.handle = nullptr;
}
FILE* get() const { return handle; }
private:
FILE* handle;
};
| 类型 | 所有权 | 线程安全 | 自定义删除器 | 典型用途 |
|---|---|---|---|---|
| unique_ptr | 独占 | 否 | 支持 | 独占资源管理 |
| shared_ptr | 共享 | 是(引用计数) | 支持 | 共享资源 |
| weak_ptr | 无 | 是 | 不支持 | 打破循环引用 |
cpp复制class Widget {
public:
static std::unique_ptr<Widget> create(int param) {
return std::unique_ptr<Widget>(new Widget(param));
}
private:
explicit Widget(int p) : param(p) {}
int param;
};
// 使用示例
auto widget = Widget::create(42);
| 容器 | 插入删除 | 随机访问 | 内存布局 | 适用场景 |
|---|---|---|---|---|
| vector | 尾部高效 | O(1) | 连续 | 需要随机访问的主要选择 |
| deque | 两端高效 | O(1) | 分块连续 | 需要头尾操作的场景 |
| list | 任意位置 | 不支持 | 非连续 | 需要频繁中间插入删除 |
| forward_list | 任意位置 | 不支持 | 非连续 | 极致节省内存的链表 |
cpp复制#include <iostream>
#include <map>
#include <unordered_map>
#include <chrono>
void benchmark() {
const int N = 1000000;
std::map<int, int> ordered_map;
std::unordered_map<int, int> hash_map;
// 插入性能测试
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < N; ++i) {
ordered_map[i] = i;
}
auto end = std::chrono::high_resolution_clock::now();
std::cout << "std::map insert: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count()
<< " ms\n";
start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < N; ++i) {
hash_map[i] = i;
}
end = std::chrono::high_resolution_clock::now();
std::cout << "std::unordered_map insert: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count()
<< " ms\n";
}
cpp复制#include <algorithm>
#include <vector>
void algorithm_examples() {
std::vector<int> v{3, 1, 4, 1, 5, 9, 2, 6};
// 排序
std::sort(v.begin(), v.end());
// 查找
auto it = std::find(v.begin(), v.end(), 5);
// 遍历处理
std::for_each(v.begin(), v.end(), [](int x) {
std::cout << x << " ";
});
// 变换
std::vector<int> squares(v.size());
std::transform(v.begin(), v.end(), squares.begin(), [](int x) {
return x * x;
});
// 条件计数
int count = std::count_if(v.begin(), v.end(), [](int x) {
return x % 2 == 0;
});
}
cpp复制struct Person {
std::string name;
int age;
};
void custom_sort() {
std::vector<Person> people{
{"Alice", 25},
{"Bob", 20},
{"Charlie", 30}
};
// 按年龄排序
std::sort(people.begin(), people.end(), [](const Person& a, const Person& b) {
return a.age < b.age;
});
// 按名字长度排序
std::sort(people.begin(), people.end(), [](const Person& a, const Person& b) {
return a.name.length() < b.name.length();
});
}
cpp复制#include <thread>
#include <iostream>
void thread_work(int id) {
std::cout << "Thread " << id << " working\n";
}
void thread_management() {
// 创建并启动线程
std::thread t1(thread_work, 1);
// 等待线程结束
t1.join();
// 分离线程
std::thread t2(thread_work, 2);
t2.detach();
// 获取硬件并发数
unsigned cores = std::thread::hardware_concurrency();
std::cout << "CPU cores: " << cores << "\n";
}
cpp复制#include <mutex>
std::mutex mtx;
int shared_data = 0;
void safe_increment() {
std::lock_guard<std::mutex> lock(mtx);
++shared_data;
}
void unsafe_increment() {
// 没有保护,可能导致数据竞争
++shared_data;
}
cpp复制#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void producer() {
std::this_thread::sleep_for(std::chrono::seconds(1));
{
std::lock_guard<std::mutex> lock(mtx);
ready = true;
}
cv.notify_one();
}
void consumer() {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{ return ready; });
std::cout << "Data is ready\n";
}
cpp复制#include <atomic>
std::atomic<int> counter(0);
void atomic_ops() {
// 安全递增
counter.fetch_add(1, std::memory_order_relaxed);
// 读取当前值
int val = counter.load(std::memory_order_acquire);
// 条件存储
int expected = 1;
counter.compare_exchange_strong(expected, 2);
}
cpp复制template<typename T>
void wrapper(T&& arg) {
// 保持参数的值类别(左值/右值)
worker(std::forward<T>(arg));
}
void worker(int& x) {
std::cout << "lvalue reference\n";
}
void worker(int&& x) {
std::cout << "rvalue reference\n";
}
void test_forwarding() {
int a = 10;
wrapper(a); // 调用lvalue版本
wrapper(20); // 调用rvalue版本
}
cpp复制template<typename T>
auto print(const T& value) -> decltype(std::cout << value, void()) {
std::cout << value << "\n";
}
void print(...) {
std::cout << "[object cannot be printed]\n";
}
void test_sfinae() {
print(42); // 使用模板版本
print(std::vector<int>()); // 使用fallback版本
}
cpp复制constexpr int factorial(int n) {
return n <= 1 ? 1 : n * factorial(n - 1);
}
void test_constexpr() {
constexpr int fact5 = factorial(5); // 编译期计算
int arr[factorial(3)]; // 数组大小在编译期确定
}
cpp复制template<int N>
struct Factorial {
static const int value = N * Factorial<N-1>::value;
};
template<>
struct Factorial<0> {
static const int value = 1;
};
void test_tmp() {
std::cout << Factorial<5>::value; // 输出120
}
| 元素类型 | 命名风格 | 示例 |
|---|---|---|
| 类/结构体 | PascalCase | MyClass |
| 函数/方法 | camelCase | calculateTotal |
| 变量 | snake_case | user_count |
| 常量 | UPPER_SNAKE | MAX_CONNECTIONS |
| 私有成员 | _leading_underscore | _internal_data |
| 模板参数 | TPascalCase | TKey, TValue |
cpp复制if (condition) {
// code
}
cpp复制#include <gtest/gtest.h>
int add(int a, int b) {
return a + b;
}
TEST(AddTest, PositiveNumbers) {
EXPECT_EQ(add(1, 2), 3);
}
TEST(AddTest, NegativeNumbers) {
EXPECT_EQ(add(-1, -1), -2);
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
cpp复制class StackTest : public ::testing::Test {
protected:
void SetUp() override {
stack.push(1);
stack.push(2);
}
std::stack<int> stack;
};
TEST_F(StackTest, PopTest) {
EXPECT_EQ(stack.top(), 2);
stack.pop();
EXPECT_EQ(stack.top(), 1);
}
bash复制# 架构特定优化
-march=native # 使用本地CPU支持的所有指令集
-mtune=native # 针对本地CPU优化调度
# 链接时优化
-flto # 启用链接时优化
-fuse-linker-plugin # 使用链接器插件提高LTO效率
# 数学优化
-ffast-math # 放宽IEEE合规要求(谨慎使用)
-fno-math-errno # 不设置errno数学函数
# 代码生成
-fomit-frame-pointer # 省略帧指针(提高性能)
-fno-exceptions # 禁用异常处理(特定场景)
bash复制# 步骤1:生成profile数据
g++ -fprofile-generate -O2 program.cpp -o program
./program train_data.txt
# 步骤2:使用profile优化
g++ -fprofile-use -O3 program.cpp -o program_optimized
cpp复制template<typename T>
class PoolAllocator {
public:
using value_type = T;
PoolAllocator(size_t pool_size) {
pool = ::operator new(pool_size * sizeof(T));
free_list = static_cast<T*>(pool);
for (size_t i = 0; i < pool_size-1; ++i) {
free_list[i].next = &free_list[i+1];
}
free_list[pool_size-1].next = nullptr;
}
T* allocate(size_t n) {
if (n != 1 || !free_list) throw std::bad_alloc();
T* result = free_list;
free_list = free_list->next;
return result;
}
void deallocate(T* p, size_t n) {
if (n != 1) return;
p->next = free_list;
free_list = p;
}
private:
union Node {
T value;
Node* next;
};
void* pool;
Node* free_list;
};
cpp复制template<typename T>
class ObjectPool {
public:
template<typename... Args>
std::unique_ptr<T, std::function<void(T*)>> acquire(Args&&... args) {
if (free_list.empty()) {
allocate_chunk();
}
T* obj = free_list.back();
free_list.pop_back();
new (obj) T(std::forward<Args>(args)...);
return std::unique_ptr<T, std::function<void(T*)>>(
obj,
[this](T* p) {
p->~T();
free_list.push_back(p);
}
);
}
private:
void allocate_chunk() {
auto chunk = std::make_unique<T[]>(chunk_size);
for (size_t i = 0; i < chunk_size; ++i) {
free_list.push_back(&chunk[i]);
}
chunks.push_back(std::move(chunk));
}
static constexpr size_t chunk_size = 64;
std::vector<std::unique_ptr<T[]>> chunks;
std::vector<T*> free_list;
};
cpp复制#if defined(_WIN32)
#define PLATFORM_WINDOWS 1
#include <windows.h>
#elif defined(__APPLE__)
#define PLATFORM_MAC 1
#include <TargetConditionals.h>
#if TARGET_OS_IPHONE
#define PLATFORM_IOS 1
#else
#define PLATFORM_MACOS 1
#endif
#elif defined(__linux__)
#define PLATFORM_LINUX 1
#endif
cpp复制#if __has_include(<filesystem>)
#include <filesystem>
namespace fs = std::filesystem;
#elif __has_include(<experimental/filesystem>)
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
#else
#error "No filesystem support"
#endif
cpp复制class FileSystem {
public:
static bool exists(const std::string& path) {
#ifdef PLATFORM_WINDOWS
DWORD attrs = GetFileAttributesA(path.c_str());
return attrs != INVALID_FILE_ATTRIBUTES;
#else
return access(path.c_str(), F_OK) == 0;
#endif
}
static uint64_t fileSize(const std::string& path) {
#ifdef PLATFORM_WINDOWS
WIN32_FILE_ATTRIBUTE_DATA fad;
if (!GetFileAttributesExA(path.c_str(),
GetFileExInfoStandard, &fad))
return 0;
return (static_cast<uint64_t>(fad.nFileSizeHigh) << 32) |
fad.nFileSizeLow;
#else
struct stat st;
if (stat(path.c_str(), &st) != 0)
return 0;
return st.st_size;
#endif
}
};
cpp复制class Thread {
public:
template<typename F>
explicit Thread(F&& f) {
#ifdef PLATFORM_WINDOWS
handle = CreateThread(nullptr, 0,
[](LPVOID arg) -> DWORD {
(*static_cast<F*>(arg))();
return 0;
}, &f, 0, nullptr);
#else
pthread_create(&handle, nullptr,
[](void* arg) -> void* {
(*static_cast<F*>(arg))();
return nullptr;
}, &f);
#endif
}
void join() {
#ifdef PLATFORM_WINDOWS
WaitForSingleObject(handle, INFINITE);
CloseHandle(handle);
#else
pthread_join(handle, nullptr);
#endif
}
private:
#ifdef PLATFORM_WINDOWS
HANDLE handle;
#else
pthread_t handle;
#endif
};
cpp复制template<typename T>
void forward_example(T&& arg) {
// 保持参数的值类别
process(std::forward<T>(arg));
}
template<typename T>
void process(T& x) {
std::cout << "lvalue: " << x << "\n";
}
template<typename T>
void process(T&& x) {
std::cout << "rvalue: " << x << "\n";
}
void test_forwarding() {
int x = 10;
forward_example(x); // 调用lvalue版本
forward_example(20); // 调用rvalue版本
}
cpp复制class Buffer {
public:
explicit Buffer(size_t size)
: size_(size), data_(new char[size]) {}
// 移动构造函数
Buffer(Buffer&& other) noexcept
: size_(other.size_), data_(other.data_) {
other.size_ = 0;
other.data_ = nullptr;
}
// 移动赋值运算符
Buffer& operator=(Buffer&& other) noexcept {
if (this != &other) {
delete[] data_;
size_ = other.size_;
data_ = other.data_;
other.size_ = 0;
other.data_ = nullptr;
}
return *this;
}
~Buffer() { delete[] data_; }
private:
size_t size_;
char* data_;
};
cpp复制template<typename T>
class ConcurrentQueue {
public:
void push(T value) {
std::lock_guard<std::mutex> lock(mutex_);
queue_.push(std::move(value));
cond_.notify_one();
}
bool try_pop(T& value) {
std::lock_guard<std::mutex> lock(mutex_);
if (queue_.empty()) return false;
value = std::move(queue_.front());
queue_.pop();
return true;
}
void wait_and_pop(T& value) {
std::unique_lock<std::mutex> lock(mutex_);
cond_.wait(lock, [this]{ return !queue_.empty(); });
value = std::move(queue_.front());
queue_.pop();
}
private:
std::queue<T> queue_;
std::mutex mutex_;
std::condition_variable cond_;
};
cpp复制template<typename F>
auto async_execute(F&& func)
-> std::future<decltype(func())>
{
using ResultType = decltype(func());
auto promise = std::make_shared<std::promise<ResultType>>();
auto future = promise->get_future();
std::thread([promise = std::move(promise),
func = std::forward<F>(func)]() {
try {
promise->set_value(func());
} catch (...) {
promise->set_exception(std::current_exception());
}
}).detach();
return future;
}
cpp复制class Shape {
public:
virtual ~Shape() = default;
virtual void draw() const = 0;
};
class Circle : public Shape {
public:
void draw() const override {
std::cout << "Drawing Circle\n";
}
};
class Rectangle : public Shape {
public:
void draw() const override {
std::cout << "Drawing Rectangle\n";
}
};
class ShapeFactory {
public:
static std::unique_ptr<Shape> create(const std::string& type) {
if (type == "Circle") return std::make_unique<Circle>();
if (type == "Rectangle") return std::make_unique<Rectangle>();
throw std::invalid_argument("Unknown shape type");
}
};
cpp复制class Button {
public:
virtual ~Button() = default;
virtual void render() const = 0;
};
class Checkbox {
public:
virtual ~Checkbox() = default;
virtual void render() const = 0;