C++:线上课程2_18(智能指针unique_ptr和工厂模式)


一、智能指针

1.default_delete(unique_ptr的默认删除器)

#ifndef MY_UNIQUE_PTR_H
#define MY_UNIQUE_PTR_H

class Object
{
public:
	Object() {}
	Object() = default;
	Object(const Object&) = delete;//拷贝构造函数不能产生
	Object& operator=(const Object&) = delete;//赋值函数不能产生
};
template<class _Ty>
class MyDeletor//删除单个对象
{
public:
	myDeletor() {}
	void operator(_Ty* ptr) const
	{
		if (ptr != nullptr)
		{
			delete ptr;
		}
	}
};

template<class _Ty>
class MyDeletor<_Ty[]>//删除一组对象
{
public:
	myDeletor() = default;
	void operator(_Ty* ptr) const
	{
		if (ptr != nullptr)
		{
			delete[]ptr;
		}
	}
};

template<class _Ty,class _Dx=MyDeletor<_Ty>>
class my_unique_ptr
{
public:
	/*//旧的命名方式(类型重命名规则)
	typedef _Ty* pointer;
	typedef _Ty element_type;
	typedef _Dx delete_type;*/
	//新的命名方式(c11类型重命名规则)
	using pointer = _Ty*;
	using element_type = _Ty;
	using delete_type = _Dx;
private:
	_Ty* _Ptr;//指针
	_Dx _myDeletor;//删除器
public:
	my_unique_ptr(const my_unique_ptr&) = delete;//删除拷贝构造函数
	my_unique_ptr& operator = (const my_unique_ptr&) = delete;//删除赋值语句
	
	my_unique_ptr(pointer _P=nullptr) :_Ptr(_P) {}
	~my_unique_ptr()
	{
		if (_Ptr != nullptr)
		{
			_myDeletor(_Ptr);
			_Ptr = nullptr;
		}
	}
	my_unique_ptr(my_unique_ptr&& _Y)
	{
		_Ptr = _Y._Ptr;
		_Y._Ptr = nullptr;
	}
	my_unique_ptr& operator=(my_unique_ptr&& _Y)
	{
		if (this == &_Y)
		{
			return *this;
		}
		reset(_Y.release());
		return *this;
	}
	_Dx& get_deleter()
	{
		return _myDeletor;
	}
	const _Dx& get_deleter() const
	{
		return _myDeletor;
	}
	pointer operator->() const
	{
		return &**this;
	}
	pointer get() const
	{
		return _Ptr;
	}
	operator bool() const//重载强制转换函数
	{
		return _Ptr != nullptr;
	}
	operator release()//释放函数
	{
		_Ty* old = _Ptr;
		_Ptr = nullptr;
		return old;
	}
	void reset(pointer _P = nullptr)//重置函数
	{
		pointer old = _Ptr;
		_Ptr = _P;
		if (old != nullptr)
		{
			_myDeletor(old);
			get_deleter()(old);
		}
	}
	void swap(my_unique_ptr _Y)//交换资源函数
	{
		std::swap(_Ptr, _Y._Ptr);
		std::swap(__myDeletor, _Y._myDeletor);
	}
};
int main()
{
	my_unique_ptr<int> op;
	my_unique_ptr<int> op2(new int(10));

	if(op) 
	{
		(*op) = 100;
	}
	if(op2) {}
}

2.修改器

release返回一个指向被管理对象的指针,并释放所有权
reset替换成被管理的对象
swap交换被管理对象

3.观察器

get返回被只想管理对象的地址
get_deleter返回用于析构被管理对象的删除器
operator bool检查是否有关联的被管理对象

4.单对象版本(unique_ptr < T >)

operator解引用指向被管理对象的指针
operator->解引用指向被管理对象的指针

5.数组版本

operator提供到被管理数组的有索引访问

二、全局函数(make_unique创建管理一个新对象的独占指针)

1.可变参数模板

template<class _Ty,class ..._Type>//可变模板参数类型
my_unique_ptr<_Ty> my_make_unique(_Type&& ... _arys)
{
	return my_unique_ptr<_Ty>(new _Ty(_arys...));
}

2.调用方式

int main()
{
    //两种调用方式相同
    std::unique_ptr<Object> op(new Object(10));
    std::unique_ptr<Object> op2 = std::make_unique<Object>(100);

    op->Value();

    return 0;
}

3.all

my_unique_ptr.h

#ifndef MY_UNIQUE_PTR_H
#define MY_UNIQUE_PTR_H

template<class _Ty>
class MyDeletor
{
public:
	//MyDeletor() = default;
	MyDeletor() {}
	void operator()(_Ty* ptr) const
	{
		if (ptr != nullptr)
		{
			delete ptr;
		}
	}
};
template<class _Ty>
class MyDeletor<_Ty[]>
{
public:
	MyDeletor() = default;
	void operator()(_Ty* ptr) const
	{
		if (ptr != nullptr)
		{
			delete[]ptr;
		}
	}
};

template<class _Ty,class _Dx=MyDeletor<_Ty>>
class my_unique_ptr
{
public:
	/*//旧的命名方式(类型重命名规则)
	typedef _Ty* pointer;
	typedef _Ty element_type;
	typedef _Dx delete_type;*/
	//新的命名方式(c11类型重命名规则)
	using pointer = _Ty*;
	using element_type = _Ty;
	using delete_type = _Dx;
private:
	_Ty* _Ptr;//指针
	_Dx _myDeletor;//删除器
public:
	my_unique_ptr(const my_unique_ptr&) = delete;//删除拷贝构造函数
	my_unique_ptr& operator = (const my_unique_ptr&) = delete;//删除赋值语句
	
	my_unique_ptr(pointer _P=nullptr) :_Ptr(_P) {}
	~my_unique_ptr()
	{
		if (_Ptr != nullptr)
		{
			_myDeletor(_Ptr);
			_Ptr = nullptr;
		}
		cout << "~my_unique_ptr: " << this << endl;
	}
	my_unique_ptr(my_unique_ptr&& _Y)
	{
		_Ptr = _Y._Ptr;
		_Y._Ptr = nullptr;
		cout << " move copy my_unique_ptr : " << this << endl;
	}
	template<class _Uy>
	my_unique_ptr& operator=(_Uy* _p)
	{
		if (this->_Ptr == (_Ty*)_p) return *this;
		if (_Ptr != nullptr) { _myDeletor(_Ptr); }
		_Ptr = _p;
		return *this;
	}
	my_unique_ptr& operator=(my_unique_ptr&& _Y)
	{
		if (this == &_Y)
		{
			return *this;
		}
		reset(_Y.release());
		cout << " move opertor=: " << endl;
		return *this;
	}
	_Dx& get_deleter()
	{
		return _myDeletor;
	}
	const _Dx& get_deleter() const
	{
		return _myDeletor;
	}
	_Ty& operator*() const
	{
		return *_Ptr;
	}
	pointer operator->() const
	{
		return &**this;
	}
	pointer get() const
	{
		return _Ptr;
	}
	operator bool() const//重载强制转换函数
	{
		return _Ptr != nullptr;
	}
	operator release()//释放函数
	{
		_Ty* old = _Ptr;
		_Ptr = nullptr;
		return old;
	}
	void reset(pointer _P = nullptr)//重置函数
	{
		pointer old = _Ptr;
		_Ptr = _P;
		if (old != nullptr)
		{
			_myDeletor(old);
		}
	}
	void swap(my_unique_ptr _Y)//交换资源函数
	{
		std::swap(_Ptr, _Y._Ptr);
		std::swap(__myDeletor, _Y._myDeletor);
	}
	_Ty& operator[](size_t _Idx) const//重载下标运算符函数
	{
		return _Ptr[_Idx];
	}
};

//class unique_ptr array
template<class _Ty, class _Dx >
class my_unique_ptr<_Ty[], _Dx>
{
public:
	using pointer = _Ty*;     
	using element_type = _Ty; 
	using delete_type = _Dx;
private:
	_Ty* _Ptr;
	_Dx  _myDeletor;
public:
	my_unique_ptr(const my_unique_ptr&) = delete;
	my_unique_ptr& operator=(const my_unique_ptr&) = delete;

	my_unique_ptr(pointer _P = nullptr) :_Ptr(_P) {}
	~my_unique_ptr()
	{
		if (_Ptr != nullptr)
		{
			_myDeletor(_Ptr);
			_Ptr = nullptr;
		}
	}
	my_unique_ptr(my_unique_ptr&& _Y)
	{
		_Ptr = _Y._Ptr;
		_Y._Ptr = nullptr;
	}
	my_unique_ptr& operator=(my_unique_ptr&& _Y)
	{
		if (this == &_Y) return *this;
		reset(_Y.release());
		//if (_Ptr != nullptr) { _myDeletor(_Ptr); }
		//_Ptr = _Y._Ptr;
		//_Y._Ptr = nullptr;
		return *this;
	}
	_Dx& get_deleter()
	{
		return _myDeletor;
	}
	const _Dx& get_deleter() const
	{
		return _myDeletor;
	}
	_Ty& operator*() const
	{
		return *_Ptr;
	}
	pointer operator->() const
	{
		return &**this;
	}
	pointer get() const
	{
		return _Ptr;
	}
	operator bool() const
	{
		return _Ptr != nullptr;
	}
	pointer release()
	{
		_Ty* old = _Ptr;
		_Ptr = nullptr;
		return old;
	}
	void reset(pointer _P = nullptr)
	{
		pointer old = _Ptr;
		_Ptr = _P;
		if (old != nullptr)
		{
			_myDeletor(old);
		}
	}
	void swap(my_unique_ptr _Y)
	{
		std::swap(_Ptr, _Y._Ptr);
		std::swap(_myDeletor, _Y._myDeletor);
	}
	_Ty& operator[](size_t _Idx) const
	{
		return _Ptr[_Idx]; 
	}
};

template<class _Ty,class ..._Type>//可变模板参数类型
my_unique_ptr<_Ty> my_make_unique(_Type&& ... _arys)
{
	return my_unique_ptr<_Ty>(new _Ty(_arys...));
}

main.cpp

#include<iostream>
#include<list>
#include<vector>
#include<queue>
#include<stack>
#include<stdio.h>
#include<algorithm>
#include"my_unique_ptr.h"
using namespace std;

class Object
{
    int value;
    int sum;
    float total;
public:
    Object(int x = 0) :value(x),sum(x),total(0)
    { 
        cout << "Create Object:" << this << endl; 
    }
    Object(int x,float ft) :value(x), sum(x), total(ft)
    {
        cout << "Create Object:" << this << endl;
    }
    ~Object() 
    {
        cout << "~Object:" << this << endl;
    }
    int& Value()
    {
        return value;
    }
    const int& Value() const
    {
        return value;
    }
};
my_unique_ptr<Object> fun()//不能以引用返回
{
    my_unique_ptr<Object> opa(new Object(10));
    return opa;
}
int main()
{
    my_unique_ptr<Object> op1;
    op1 = fun();
    return 0;
}

调用方式
在这里插入图片描述

三、工厂模式

1.概述

  • 在简单工厂模式中只提供一个工厂类,该工厂类处于对产品类进行实例化的中心位置,它需要知道每一个产品对象的创建细节,并决定何时实例化哪一个产品类。简单工厂模式最大的缺点是当有新产品要加入到系统中时,必须修改工厂类,需要在其中加入必要的业务逻辑,这违背了"开闭原则。"此外,在简单工厂模式中,所有的产品都由同一个工厂创建,工厂类职责较重,业务逻辑较为复杂,具体产品与工厂类之间的耦合度高,严重影响了系统的灵活性和扩展性,而工厂方法模式则可以很好地解决这一问题。
  • 在工厂方法模式中,我们不再提供一个统一的工厂类来创建所有的产品对象,而是针对不同的产品提供不同的工厂,系统提供一个与产品等级结构相对应的工厂等级结构。
  • 工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。工厂方法模式又简称为工厂模式(Factory Pattern),又可称作虚拟构造器模式(virtual constructor Pattern)或多态工厂模式(Po1ymorphic Factory Pattern)。工厂方法模式是一种类创建型模式。

2.结构模式图

在这里插入图片描述

3.包含内容

  • Product(抽象产品)︰它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的公共父类。
    oConcreteProduct(具体产品)︰它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品之间——对应。
  • Factory(抽象工厂)︰在抽象工厂类中,声明了工厂方法(Factory Method),用于返回一个产品。抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。
  • ConcreteFactory(具体工厂)∶它是抽象工厂类的子类,实现了抽象工厂中定义的工厂方法,并可由客户端调用,返回一个具体产品类的实例。

与简单工厂模式相比,工厂方法模式最重要的区别是引入了抽象工厂角色,抽象工厂可以是接口,也可以是抽象类或者具体类,其典型代码如下所示:

struct Factory
{
	virtual Product * factoryMethod();
};

在抽象工厂中声明了工厂方法但并未实现工厂方法,具体产品对象的创建由其子类负责,客户端针对抽象工厂编程,可在运行时再指定具体工厂类,具体工厂类实现了工厂方法,不同的具体工厂可以创建不同的具体产品,其典型代码如下所示:

class ConcreteFactory:public Factory
{
public:
	virtual Pactory * factoryMethod()
	{
		return new ConcreteProduct();
	}
};

4.代码示例

#define  _CRT_SECURE_NO_WARNINGS 
#include<iostream>
#include<list>
#include<type_traits>
#include<initializer_list>
#include<string>
#include<memory>
#include<stdio.h>
#include<map>
using namespace std;

#include"my_unique_ptr.h"

//日志记录器接口:抽象产品
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; }
	virtual ~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());
		//return my_make_unique<DatabaseLogger>();
	}
};

//文件日志记录器工厂类:具体工厂
class FileLoggerFactory :public LoggerFactory
{
public:
	FileLoggerFactory() { cout << "FileLoggerFactory" << endl; }
	~FileLoggerFactory() { cout << "~FileLoggerFactory" << endl; }
	my_unique_ptr<Logger> createLogger()
	{
		//创建文件日志记录器对象
		//Logger* logger = new FileLogger();
		//创建文件,代码省略
		//return logger;
		return my_unique_ptr<Logger>(new FileLogger());
	}
};

//编写如下客户端测试代码
//Client
int main()
{
	my_unique_ptr<LoggerFactory> factory(new FileLoggerFactory());
	my_unique_ptr<Logger> logger = factory->createLogger();

	logger->writeLog();

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


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值