C++ 智能指针和工厂模式

智能指针和工厂方法模式

工厂方法模式

简单工厂模式虽然简单,但存在一个很严重的问题,当系统中需要引入新产品时,由于静态工厂方法通过所传入参数的不同来创建不同的产品,这必定要修改工厂类的源代码,将违背“开闭原则”,如何实现增加新产品而不影响已有代码?工厂方法模式应运而生,本文将介绍第二种工厂模式——工厂方法模式

  • 日志记录器的设计

软件公司欲开发一个系统运行日志记录器,该记录器可以通过多种途径保存系统的运行日志,如通过文件记录或数据库记录,用户可以通过修改配置文件灵活地更换日志记录方式,在设计各类日志记录器时,软件公司的开发人员发现需要对日志记录器进行一些初始化工作,初始化参数的设置过程较为复杂,而且某些参数的设置有严格的先后次序,否则可能会发生记录失败;如何封装记录器的初始化过程并保证多种记录器切换的灵活性时软件公司开发人员面临的一个难题

该日志记录器有两个设计要点:

  1. 需要封装日志记录器的初始化过程,这些初始化工作较为复杂,例如需要初始化其他的类,还有可能需要读取配置文件,导致代码较长,如果将它们都卸载构造函数中,会导致构造函数庞大,不利于代码的修改和维护
  2. 用户可能需要更换日志记录方式,在客户端代码中需要提供一种灵活的方式来选择日志记录器,尽量在不修改源代码的基础上更换或者增加日志记录方式

在这里插入图片描述

工厂模式实例

这里使用了上一文章中的代码
C++ 智能指针: 链接.

//日志记录器接口:抽象产品
struct Logger
{
	virtual void writeLog() = 0;
	Logger() 
	{
		cout << "日志记录器接口" << endl;
	}
	virtual ~Logger() //会先析构子类再析构基类
	{
		cout << "~Logger:" << endl;
	}
};

//数据库日志记录器:具体产品
class DatabaseLogger :public Logger
{
public:
	DatabaseLogger()
	{
		cout << "DatabaseLogger::" << endl;
	}
	~DatabaseLogger()
	{
		cout << "~DatabaseLogger::" << endl;
	}
	void writeLog() 
	{
		cout << "数据库日志记录" << endl;
	}
};

//文件日志记录器:具体产品
class FileLogger :public Logger
{
public:
	FileLogger()
	{
		cout << "FileLogger::" << endl;
	}
	~FileLogger()
	{
		cout << "~FileLogger" << endl;
	}
	void writeLog()
	{
		cout << "文件日志记录" << endl;
	}
};

//日志记录器工厂接口:抽象工厂
struct LoggerFactory
{
	virtual my_unique_ptr<Logger> createLogger() = 0;
	LoggerFactory()
	{
		cout << "LoggerFactory" << endl;
	}
	~LoggerFactory()
	{
		cout << "~LoggerFactory" << endl;
	}
};

//数据库日志记录器工厂类:具体工厂
class DatabaseLoggerFactory :public LoggerFactory
{
public:
	DatabaseLoggerFactory()
	{
		cout << "DatabaseLoggerFactory" << endl;
	}
	~DatabaseLoggerFactory()
	{
		cout << "~DatabaseLoggerFactory" << endl;
	}
	my_unique_ptr<Logger> createLogger()
	{
		//连接数据库,代码胜利
		//创建数据库日志记录器对象
		//Logger* logger = new DatabaseLogger();
		//初始化数据库日志记录器
		return my_unique_ptr<Logger>(new DatabaseLogger());//数据库日志记录器创建
	}
}; 

//文件日志记录器工厂类:具体工厂
class FileLoggerFactory :public LoggerFactory
{
public:
	FileLoggerFactory()
	{
		cout << "FileLoggerFactory" << endl;
	}
	~FileLoggerFactory()
	{
		cout << "~FileLoggerFactory" << endl;
	}
	my_unique_ptr<Logger> createLogger()
	{
		return my_unique_ptr<Logger>(new FileLogger());
	}
};

int main()
{
	my_unique_ptr<LoggerFactory> factory(new FileLoggerFactory());//文件日志记录器工厂
	my_unique_ptr<Logger> logger = factory->createLogger();

	logger->writeLog();

	factory.reset(new DatabaseLoggerFactory());
	logger = factory->createLogger();
	logger->writeLog();
	return 0;
}

在这里插入图片描述
最终对象的析构由智能指针进行操作,智能指针自动进行堆区空间的管理

而相对于C++为什么没有垃圾回收机制

因为在程序的编写中,使用到了堆区的资源,但是由于应用场景与管理方式不同,C++可以根据业务需求去完成内存池的管理

### C++ 智能指针详解 #### 定义与作用 智能指针是一种类模板,用于管理动态分配的对象生命周期。通过自动处理对象的创建销毁,智能指针能够有效防止内存泄漏其他资源管理错误。 #### 类型介绍 C++标准库提供了三种主要类型的智能指针: - **unique_ptr** `std::unique_ptr` 是一种独占所有权的智能指针,不允许复制操作,但支持移动语义[^1]。 ```cpp std::unique_ptr<int> ptr(new int(10)); ``` - **shared_ptr** `std::shared_ptr` 实现了引用计数机制,允许多个指针共享同一个对象实例。当最后一个指向该对象的 `shared_ptr` 被销毁或重置时,所管理的对象也会被删除[^2]。 ```cpp auto sptr = std::make_shared<int>(20); ``` - **weak_ptr** `std::weak_ptr` 不增加引用计数,通常作为辅助工具配合 `shared_ptr` 使用,主要用于解决循环引用问题[^3]。 ```cpp std::weak_ptr<int> wptr(sptr); ``` #### 应用场景示例 假设有一个简单的工厂模式实现,其中涉及到了不同种类的产品生产。为了简化代码并提高安全性,可以采用智能指针来代替原始裸指针。 ```cpp #include <memory> #include <iostream> // 基础产品接口定义 struct Product { virtual ~Product() {} virtual void use() const = 0; }; // 具体产品的实现之一 struct ConcreteProductA : public Product { void use() const override { std::cout << "Using product A\n"; } }; // 工厂函数返回智能指针而非普通指针 std::unique_ptr<Product> create_product_a() { return std::make_unique<ConcreteProductA>(); } int main() { // 自动管理内存,无需手动delete auto prod = create_product_a(); prod->use(); return 0; } ``` 上述例子展示了如何利用 `std::unique_ptr` 来安全地管理传递堆上分配的对象,而不需要担心忘记释放资源的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值