在C++中,“工厂”(Factory)是一种设计模式,它提供了一种创建对象的方式,将对象的创建和使用代码分离开来,提高了代码的可扩展性和可维护性。
工厂模式通过一个共同的接口或基类来定义产品对象的创建方法,而具体的对象创建过程则由子类或具体工厂来实现。通过使用工厂模式,我们可以隐藏对象的创建细节,使客户端代码只关心使用对象而不必关心对象的创建方式。
工厂模式常见的几种变体包括:
-
简单工厂模式(Simple Factory):由一个工厂类负责创建所有的产品对象,根据不同的传入参数返回不同的产品实例。
-
工厂方法模式(Factory Method):通过定义一个创建对象的接口,让子类决定实例化哪个类。每个具体子类都对应一个具体产品。
-
抽象工厂模式(Abstract Factory):提供一个创建相关或依赖对象族的接口,而无需指定具体类。不同的具体工厂类可以创建不同类别的产品对象。
工厂模式在实际开发中常用于:
- 封装对象的具体创建过程,隐藏对象的实现细节;
- 实现创建对象的灵活性,方便根据需求变化创建不同的对象;
- 遵循开闭原则,提高代码的可扩展性和可维护性。
需要注意的是,工厂模式并不是万能的,适用于需要创建复杂对象、对象创建过程涉及多个步骤或对象创建涉及多个类的情况。对于简单的对象创建,直接使用构造函数就足够了。
通过工程来构建任意参数对象
advanced.h
#pragma once
#include <iostream>
#include <type_traits>
using namespace std;
//定义
template<int ...>//定义一个接受任意数量整数参数的模板函数
struct HelloIndex
{
};
//通过using展开的中间值
template<int N, int ...ParamTypes>
struct SpawnIndex
{
using Type = typename SpawnIndex<N - 1, N - 1, ParamTypes...>::Type;
//typename 来明确告诉编译器该名称是类型而不是值
};
//循环终止
template<int ... ParamTypes>
struct SpawnIndex<0, ParamTypes ...>
{
typedef HelloIndex<ParamTypes...>Type;
};
//工厂
template<class T>
T* CreateObject()//创建一个无参的T对象的工厂函数
{
return new T();
}
template<class T, class Arg0>
T* CreateObject()//创建一个带一个参数的T对象的工厂函数
{
return new T(Arg0);
}
template<class T,class Arg1,class Arg2>
T* CreateObject()
{
return new T(Arg1, Arg2);
}
//改变为可变参数可以大大节省了代码量(和上面相比)
template<class T, class ...ParamTypes>
T* CreateObject(ParamTypes &&...Param)//创建一个可变参数的T对象的工厂函数,可以接受任意数量的参数
{
//return new T(Param...);//会产生一个拷贝,下面代码不会产生拷贝
return new T(std::forward<ParamTypes>(Param)...);
//使用std::forward将参数引用传递给T对象的构造函数,并返回创建的对象的指针
//这样可以避免产生不必要的拷贝
}
学习.cpp
#include <iostream>
#include"advanced.h"
struct FTestA
{
};
struct FTestB
{
FTestB(int a, int b)
{
}
};
int main()
{
SpawnIndex<10>::Type* Hello = CreateObject<SpawnIndex<10>::Type>();
//using Hello = CreateObject<SpawnIndex<10>::Type>();
if (Hello)
{
}
FTestA* p = CreateObject<FTestA>();
FTestB* p2 = CreateObject<FTestB>(1,2);
return 0;
}
&&
折叠
可以看作是引用的引用
&& 表示右值引用(rvalue reference)。它是C++11引入的一种新的引用类型,用于支持移动语义和完美转发
在C++17中,引入了参数包展开的语法,使得对模板参数包(parameter pack)的操作更加便捷和灵活。其中,参数包展开支持对右值引用的折叠(rvalue reference collapsing),即将多个右值引用折叠为一个右值引用
std::forward
https://www.cnblogs.com/oniisan/p/moveFunction.html
用在泛型代码中进行完美转发
完美转换,传入左值,把左值引用传递,传入右值,把右值引用传递,通过此方式避免拷贝
头文件:
#include <type_traits>文章来源地址https://www.toymoban.com/news/detail-671274.html
std::move
左值或右值都转换为右值引用文章来源:https://www.toymoban.com/news/detail-671274.html
头文件:
#include <type_traits>
到了这里,关于12,【设计模式】工厂的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!