在掘金逛C++帖子时,总能看到新手问"为什么我的代码能跑但总被review打回"?其实很多时候不是逻辑错了,而是没掌握这些"进阶偏基础"的实用技巧------既能少踩坑,又能让代码更简洁高效,配上极简例子一看就会~
1. 前向声明:头文件依赖的"减负神器"
还在头文件里疯狂#include?前向声明能直接减少编译依赖,还能解决循环依赖问题 !
cpp
// forward.h (集中存放前向声明)
#pragma once
class Document; // 无需包含完整定义,声明即可
// my_class.h
#include "forward.h"
#include <memory>
class MyClass {
std::unique_ptr<Document> doc; // 指针/引用类型只需前向声明
};
核心优势:编译速度翻倍,避免"改一个头文件全工程重编"的痛苦。
2. emplace_back:容器插入的"性能王者"
别再用push_back了!emplace_back直接在容器内构造对象,省去临时对象拷贝的开销 。
cpp
#include <vector>
#include <string>
std::vector<std::string> vec;
vec.push_back(std::string("hello")); // 先构造临时对象,再拷贝
vec.emplace_back("world"); // 直接在vector里构造,零拷贝
适用场景:所有支持的STL容器(vector、list、map等),插入复杂对象时效果超明显。
3. 静态工厂方法:对象创建的"安全卫士"
构造函数没法返回错误?静态工厂方法能优雅处理对象创建失败,避免部分初始化的坑 。
cpp
#include <optional>
#include <fstream>
class FileProcessor {
public:
// 静态工厂方法,创建失败返回nullopt
static std::optional<FileProcessor> create(const std::string& filename) {
std::ifstream file(filename);
if (!file.is_open()) return std::nullopt;
return FileProcessor(std::move(file)); // 私有构造确保初始化成功
}
private:
explicit FileProcessor(std::ifstream file) : file_(std::move(file)) {}
std::ifstream file_;
};
// 使用:创建成功才执行逻辑
if (auto processor = FileProcessor::create("data.txt")) {
processor->process();
}
4. 结构化绑定:解包的"懒人福音"
不用再写get<0>、get<1>了!结构化绑定能直接解包tuple/pair,代码清爽到飞起。
cpp
#include <tuple>
#include <string>
// 返回多个值的函数
std::tuple<int, std::string, float> getUser() {
return {101, "张三", 95.5};
}
int main() {
auto [id, name, score] = getUser(); // 直接绑定三个变量
// id=101, name="张三", score=95.5
return 0;
}
5. 作用域守卫:资源清理的"自动管家"
怕函数中途return导致资源泄漏?作用域守卫能确保离开作用域时自动执行清理逻辑 。
cpp
#include <functional>
class ScopeGuard {
public:
explicit ScopeGuard(std::function<void()> cleanup)
: cleanup_(std::move(cleanup)), active_(true) {}
~ScopeGuard() { if (active_) cleanup_(); }
void dismiss() { active_ = false; } // 可取消清理
private:
std::function<void()> cleanup_;
bool active_;
};
void writeFile() {
FILE* file = fopen("temp.txt", "w");
ScopeGuard guard([&]() { if (file) fclose(file); }); // 自动关文件
if (someError()) return; // 即使提前返回,文件也会关闭
}
6. constexpr:编译期计算的"性能加速器"
把能在编译期算的逻辑交给编译器,运行时零开销,还能用作常量表达式 。
cpp
// 编译期计算阶乘
constexpr int factorial(int n) {
return n <= 1 ? 1 : n * factorial(n - 1);
}
int main() {
constexpr int size = factorial(5); // 编译时就算出120
int arr[size]; // 可直接用作数组大小
return 0;
}