1. 类设计思路
- 网络连接类 (
NetworkConnection
):封装网络连接相关操作,利用RAII在析构函数中关闭连接。
- 文件句柄类 (
FileHandle
):封装文件操作相关,利用RAII在析构函数中关闭文件。
- 数据库事务类 (
DatabaseTransaction
):封装数据库事务操作,利用RAII在析构函数中提交或回滚事务。
- 资源管理器类 (
ResourceManager
):管理上述三种资源,利用智能指针确保资源的正确初始化、释放和异常安全。
2. 代码实现
#include <iostream>
#include <memory>
#include <string>
// 网络连接类
class NetworkConnection {
public:
NetworkConnection(const std::string& ip, int port) {
std::cout << "Connecting to " << ip << ":" << port << std::endl;
// 实际连接操作代码
}
~NetworkConnection() {
std::cout << "Closing network connection" << std::endl;
// 实际关闭连接操作代码
}
};
// 文件句柄类
class FileHandle {
public:
FileHandle(const std::string& filename) {
std::cout << "Opening file " << filename << std::endl;
// 实际打开文件操作代码
}
~FileHandle() {
std::cout << "Closing file" << std::endl;
// 实际关闭文件操作代码
}
};
// 数据库事务类
class DatabaseTransaction {
public:
DatabaseTransaction() {
std::cout << "Starting database transaction" << std::endl;
// 实际开始事务操作代码
}
~DatabaseTransaction() {
std::cout << "Rolling back database transaction" << std::endl;
// 实际回滚事务操作代码
}
void commit() {
std::cout << "Committing database transaction" << std::endl;
// 实际提交事务操作代码
}
};
// 资源管理器类
class ResourceManager {
public:
ResourceManager(const std::string& ip, int port, const std::string& filename)
: networkConn(std::make_unique<NetworkConnection>(ip, port)),
fileHandle(std::make_unique<FileHandle>(filename)),
dbTransaction(std::make_unique<DatabaseTransaction>()) {
std::cout << "All resources initialized" << std::endl;
}
~ResourceManager() {
std::cout << "ResourceManager destructor: Releasing all resources" << std::endl;
// 智能指针会自动调用各自资源的析构函数
}
void doWork() {
try {
// 在这里执行依赖这些资源的业务逻辑
std::cout << "Doing work with network, file and database" << std::endl;
// 模拟异常情况
throw std::runtime_error("Simulated error");
dbTransaction->commit();
} catch (const std::exception& e) {
std::cerr << "Exception caught: " << e.what() << std::endl;
// 异常情况下,智能指针会自动释放资源
}
}
private:
std::unique_ptr<NetworkConnection> networkConn;
std::unique_ptr<FileHandle> fileHandle;
std::unique_ptr<DatabaseTransaction> dbTransaction;
};
3. 测试代码
int main() {
try {
ResourceManager manager("127.0.0.1", 8080, "example.txt");
manager.doWork();
} catch (const std::exception& e) {
std::cerr << "Unhandled exception in main: " << e.what() << std::endl;
}
return 0;
}
4. 说明
- 资源初始化:在
ResourceManager
的构造函数中,通过std::make_unique
创建三种资源的实例,确保资源被正确初始化。
- 资源释放:
ResourceManager
的析构函数依赖智能指针std::unique_ptr
的自动析构特性,当ResourceManager
对象销毁时,会自动调用所管理资源的析构函数,释放网络连接、文件句柄和数据库事务。
- 异常安全:在
doWork
函数中,若发生异常,由于资源由智能指针管理,它们会在异常离开作用域时自动释放,避免资源泄漏。同时,DatabaseTransaction
在异常情况下会回滚事务,保证数据一致性。