C++高频知识点(十三)vector内存扩展问题、单例模式,懒汉模式/饿汉模式,及线程安全问题、工厂模式及简单工厂模式、类成员函数后加const,有什么作用?指针和引用的区别
·
文章目录
61. vector内存扩展问题,扩容

代码示例
以下代码展示了std::vector的内存扩展过程:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec;
std::cout << "Initial capacity: " << vec.capacity() << std::endl;
for (int i = 1; i <= 10; ++i) {
vec.push_back(i);
std::cout << "Size: " << vec.size() << ", Capacity: " << vec.capacity() << std::endl;
}
//capacity 这东西是成倍数增加的
return 0;
}


62. 单例模式,懒汉模式/饿汉模式,及线程安全问题
关于设计模式,可以看我主页的专栏,有专门介绍
单例模式是一种常用的设计模式,确保一个类只有一个实例,并提供一个全局访问点。它可以分为两种:懒汉模式和饿汉模式。
饿汉模式的代码实现
class Singleton {
private:
// 静态指针,指向单例实例
static Singleton* instance;
//注意这里: 私有构造函数,防止外部实例化
Singleton() {}
public:
// 返回单例实例的公共静态方法
static Singleton* getInstance() {
return instance;
}
};
// 类外初始化静态成员变量,实例在类加载时就创建
Singleton* Singleton::instance = new Singleton();
懒汉模式的代码实现
非线程安全实现:
class Singleton {
private:
// 静态指针,指向单例实例
static Singleton* instance;
// 私有构造函数,防止外部实例化
Singleton() {}
public:
// 返回单例实例的公共静态方法
static Singleton* getInstance() {
// 第一次调用时创建实例
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
};
// 类外初始化静态成员变量
Singleton* Singleton::instance = nullptr;
线程安全的懒汉模式
1. 使用互斥锁(Mutex):
#include <mutex>
class Singleton {
private:
// 静态指针,指向单例实例
static Singleton* instance;
// 静态互斥锁,保护实例创建过程
static std::mutex mtx;
// 私有构造函数,防止外部实例化
Singleton() {}
public:
// 返回单例实例的公共静态方法
static Singleton* getInstance() {
// 锁住互斥锁,确保线程安全
std::lock_guard<std::mutex> lock(mtx);
// 第一次调用时创建实例
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
};
// 类外初始化静态成员变量
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;
2. 双重检查锁定:
#include <mutex>
class Singleton {
private:
// 静态指针,指向单例实例
static Singleton* instance;
// 静态互斥锁,保护实例创建过程
static std::mutex mtx;
// 私有构造函数,防止外部实例化
Singleton() {}
public:
// 返回单例实例的公共静态方法
static Singleton* getInstance() {
// 第一次检查,避免不必要的锁
if (instance == nullptr) {
// 锁住互斥锁,确保线程安全
std::lock_guard<std::mutex> lock(mtx);
// 第二次检查,确保实例唯一
if (instance == nullptr) {
instance = new Singleton();
}
}
// 为啥子 要进行两次检查????
//如果检查一次(里面的那个),这种实现虽然是线程安全的,
//但每次调用 getInstance() 都会加锁和解锁,这会导致性能开销。
//双重检查锁定通过在加锁前后各进行一次检查,避免了不必要的加锁操作,提高了性能.
return instance;
}
};
// 类外初始化静态成员变量
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;
3. 使用C++11标准的局部静态变量:
class Singleton {
private:
// 私有构造函数,防止外部实例化
Singleton() {}
public:
// 返回单例实例的公共静态方法
static Singleton& getInstance() {
// 局部静态变量,C++11保证线程安全
static Singleton instance;
return instance;
}
};
// 使用示例
int main() {
// 获取单例实例的引用
Singleton& singletonInstance = Singleton::getInstance();
return 0;
}
63. 工厂模式及简单工厂模式
工厂模式(Factory Pattern)和简单工厂模式(Simple Factory Pattern)是两种常见的设计模式,用于创建对象而不需要在代码中显式指定要创建的具体类。这些模式提高了代码的灵活性和可维护性。

简单工厂模式的代码实现
#include <iostream>
#include <string>
// 产品抽象基类
class Product {
public:
virtual void use() = 0;
virtual ~Product() {}
};
// 具体产品类A
class ConcreteProductA : public Product {
public:
void use() override {
std::cout << "使用产品A" << std::endl;
}
};
// 具体产品类B
class ConcreteProductB : public Product {
public:
void use() override {
std::cout << "使用产品B" << std::endl;
}
};
// 简单工厂类
class SimpleFactory {
public:
static Product* createProduct(const std::string& type) {
if (type == "A") {
return new ConcreteProductA();
} else if (type == "B") {
return new ConcreteProductB();
} else {
return nullptr;
}
}
};
// 使用示例
int main() {
//需要什么就传入类名,由工厂帮你实例对象
Product* productA = SimpleFactory::createProduct("A");
if (productA) {
productA->use();
delete productA;
}
Product* productB = SimpleFactory::createProduct("B");
if (productB) {
productB->use();
delete productB;
}
return 0;
}
工厂模式的代码实现
#include <iostream>
#include <string>
// 产品抽象基类
class Product {
public:
virtual void use() = 0;
virtual ~Product() {}
};
// 具体产品类A
class ConcreteProductA : public Product {
public:
void use() override {
std::cout << "使用产品A" << std::endl;
}
};
// 具体产品类B
class ConcreteProductB : public Product {
public:
void use() override {
std::cout << "使用产品B" << std::endl;
}
};
// 工厂方法抽象基类,这里又抽象了一层
class Factory {
public:
virtual Product* createProduct() = 0;
virtual ~Factory() {}
};
// 具体工厂类A
class ConcreteFactoryA : public Factory {
public:
Product* createProduct() override {
return new ConcreteProductA();
}
};
// 具体工厂类B
class ConcreteFactoryB : public Factory {
public:
Product* createProduct() override {
return new ConcreteProductB();
}
};
//理论上,有多少个类,就应该有多少个对应的具体的工厂类,这工作量老嗨了
// 使用示例
int main() {
Factory* factoryA = new ConcreteFactoryA();
Product* productA = factoryA->createProduct();
if (productA) {
productA->use();
delete productA;
}
delete factoryA;
Factory* factoryB = new ConcreteFactoryB();
Product* productB = factoryB->createProduct();
if (productB) {
productB->use();
delete productB;
}
delete factoryB;
return 0;
}
抽象工厂、工厂模式、简单工厂的区别

64. 类成员函数后加const,有什么作用?

代码示例
#include <iostream>
class MyClass {
public:
MyClass(int val) : value(val) {}
// 常量成员函数
int getValue() const {
return value;
}
// 非常量成员函数
void setValue(int val) {
value = val;
}
private:
int value;
};
int main() {
const MyClass obj(42); // 常量对象
std::cout << "Value: " << obj.getValue() << std::endl;
// obj.setValue(100);
// 错误:不能调用非常量成员函数,也就说能读不能写。如果非要写 你就得学习mutable了
return 0;
}
65. 指针和引用的区别

之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!
更多推荐

所有评论(0)