C++回顾
- 其他
- 2025-03-27
- 98热度
- 0评论
平时用C++比较少,最近项目需要用到C++,现简单再回顾一下。
单例模式
在某些场景下,一个类只需要有一个实例就足够了,例如配置管理类、日志记录器、数据库连接池等。使用单例模式可以避免创建多个实例导致的资源浪费、数据不一致等问题。
单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来获取该实例。在程序运行期间,这个类的实例始终只有一个,所有对该类实例的访问都通过这个全局访问点进行。
#include <iostream>
class Board {
private:
// 私有构造函数,防止外部实例化
Board() {}
// 禁止拷贝构造函数
Board(const Board&) = delete;
// 禁止赋值运算符
Board& operator=(const Board&) = delete;
static Board* instance;
public:
// 静态方法,用于获取唯一实例
static Board& GetInstance() {
if (instance == nullptr) {
instance = new Board();
}
return *instance;
}
void printMessage() {
std::cout << "This is the Board instance." << std::endl;
}
};
// 初始化静态成员变量
Board* Board::instance = nullptr;
int main() {
Board& board = Board::GetInstance();
board.printMessage();
return 0;
}
智能指针
在传统的 C++ 中,使用 new 运算符手动分配内存,需要使用 delete 运算符手动释放内存。如果忘记释放内存,就会导致内存泄漏。使用智能指针可以自动管理对象的生命周期,避免内存泄漏的问题。
std::make_unique 是 C++14 引入的一个函数模板,用于创建 std::unique_ptr 对象。std::unique_ptr 是一种智能指针,它对所指向的对象拥有唯一所有权,即同一时间只能有一个 std::unique_ptr 指向同一个对象。当 std::unique_ptr 被销毁时,它所指向的对象也会被自动销毁。
#include <iostream>
#include <memory>
class MyClass {
public:
MyClass() {
std::cout << \"MyClass constructor\" << std::endl;
}
~MyClass() {
std::cout << \"MyClass destructor\" << std::endl;
}
void doSomething() {
std::cout << \"Doing something...\" << std::endl;
}
};
int main() {
// 使用 std::make_unique 创建 std::unique_ptr
auto ptr = std::make_unique<MyClass>();
ptr->doSomething();
// 当 ptr 离开作用域时,MyClass 对象会自动销毁
return 0;
}
Lambda 表达式
Lambda 表达式的主要优点是简洁性和灵活性。在一些场景下,我们只需要一个简单的函数,而且这个函数只在某个特定的地方使用一次,使用 Lambda 表达式可以避免定义一个单独的命名函数,使代码更加简洁。
Lambda 表达式是 C++11 引入的一种匿名函数机制,它允许在代码中定义一个临时的、没有名称的函数。Lambda 表达式可以捕获外部变量,从而在函数内部使用这些变量。
[capture list] (parameter list) mutable(可选) -> return type(可选) { function body }
实例,lambda一般用于设置回调函数。
codec->OnInputReady([this, codec]() {
// 捕获列表 [this, codec] 表示捕获当前对象和 codec 变量
xEventGroupSetBitsFromISR(...);
return ...;
});
移动语义std::move
在某些情况下,对象的拷贝操作可能会非常昂贵,例如对象包含大量的数据或者动态分配的内存。使用移动语义可以避免这些不必要的拷贝操作,提高程序的性能。
移动语义是 C++11 引入的一个重要特性,它允许将对象的资源所有权从一个对象转移到另一个对象,避免不必要的拷贝操作。std::move 是一个标准库函数,用于将左值转换为右值引用,从而触发移动构造函数或移动赋值运算符。
#include <iostream>
#include <vector>
class MyVector {
private:
std::vector<int> data;
public:
MyVector(const std::vector<int>& vec) : data(vec) {
std::cout << \"Copy constructor called\" << std::endl;
}
// 移动构造函数
MyVector(MyVector&& other) noexcept : data(std::move(other.data)) {
std::cout << \"Move constructor called\" << std::endl;
}
void printSize() {
std::cout << \"Size: \" << data.size() << std::endl;
}
};
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
MyVector v1(vec);
// 使用 std::move 调用移动构造函数
MyVector v2(std::move(v1));
v2.printSize();
return 0;
}
在上述代码中,std::move(v1) 将 v1 转换为右值引用,从而调用 MyVector 的移动构造函数。移动构造函数将 v1 的 data 资源所有权转移到 v2,避免了不必要的拷贝操作。