【C++】工厂函数和工厂模式
目录
工厂函数
c++ define 定义工厂函数,其中define函数名使用##连接
# include<stdio.h>
# include <stdlib.h> //atoi
# include <string.h> //strlen
# include <stdint.h> //uint64_t
#include<iostream>
#include<memory>
using namespace std;
template <class T>
int DoAllreduce(T tensor, T output) {
return tensor+output;
}
#define ALLREDUCE(torch_Tensor, THTensor) \
extern "C" int horovod_torch_allreduce_async_##torch_Tensor( \
THTensor tensor, THTensor output) { \
printf("this is all reduce!\n");\
DoAllreduce(1,1);\
return 0; \
}
ALLREDUCE(torch_bbyte,int)
ALLREDUCE(torch_bbyte2,int)
int main(){
horovod_torch_allreduce_async_torch_bbyte(1,1);
horovod_torch_allreduce_async_torch_bbyte2(1,1);
return 0;
}
输出:
this is a construc function!
the sum of A is 3
share_ptr:00871244
请按任意键继续. . .
区别#与##
# 是把参数字符串化,## 是将两个参数连为一个整体。
#include <iostream>
#include <cstdlib>
// 测试不带 # 号的效果
#define NO_NUMBER_SIGN(x) x
// 测试一个 # 号的效果
#define SINGLE_NUMBER_SIGN(x) #x
// 测试两个 # 号的效果
#define DOUBLE_NUMBER_SIGN(x, y) x##y
int main()
{
// 测试不带 # 号的效果:hello 不加双引号报错(error C2065: “hello”: 未声明的标识符)
std::cout << NO_NUMBER_SIGN("hello") << std::endl;
// 测试一个 # 号的效果:world 加不加双引号都可以,因为 # 将其字符串化
std::cout << SINGLE_NUMBER_SIGN(world) << std::endl;
// 测试两个 # 号的效果:连接两个对象
std::cout << DOUBLE_NUMBER_SIGN("hello", "world") << std::endl;
system("pause");
return 0;
}
输出:
hello
world
helloworld
简单工厂模式
简单工厂模式可以说是大多数人接触到的第一个设计模式。资源请求者(客户)直接调用工厂类中的函数,工厂根据传入的参数返回不同的类给资源请求者。下面给出在C++中使用简单工厂模式的一个demo,采用了auto_ptr智能指针管理类资源。
值得注意的是抽象类Product中的析构函数必须为虚函数。《Effective C++》条款07:为多态基类声明virtual析构函数。
采用auto_ptr也符合《Effective C++》条款13:以对象管理资源、条款18:让接口容易被正确使用,不易被误用。
#include <iostream>
using namespace std;
enum ProductType{ TypeA, TypeB, TypeC };
class Product{
public:
virtual void show() = 0;
virtual ~Product(){};//virtual destructor
};
class ProductA :public Product{
public:
void show(){
cout << "A" << endl;
}
ProductA(){
cout << "constructing A" << endl;
}
~ProductA(){
cout << "destructing A" << endl;
}
};
class ProductB :public Product{
public:
void show(){
cout << "B" << endl;
}
ProductB(){
cout << "constructing B" << endl;
}
~ProductB(){
cout << "destructing B" << endl;
}
};
class ProductC :public Product{
public:
void show(){
cout << "C" << endl;
}
ProductC(){
cout << "constructing C" << endl;
}
~ProductC(){
cout << "destructing C" << endl;
}
};
class ProductFactory{
public:
static auto_ptr<Product> createProduct(ProductType type){
switch (type){
case TypeA: return auto_ptr<Product>(new ProductA());
case TypeB: return auto_ptr<Product>(new ProductB());
case TypeC: return auto_ptr<Product>(new ProductC());
default: return auto_ptr<Product>(NULL);
}
}
};
int main()
{
{
auto_ptr<Product> proA = ProductFactory::createProduct(TypeA);
auto_ptr<Product> proB = ProductFactory::createProduct(TypeB);
auto_ptr<Product> proC = ProductFactory::createProduct(TypeC);
proA->show();
proB->show();
proC->show();
}
system("pause");
}
https://www.cnblogs.com/caiminfeng/p/5311934.html
c++小技巧,宏定义工厂函数
这几天在写鱼类抽象的时候,发现原来使用父类指针创建,替换,转化子类对象的方法原来叫工厂模式,以前常常用这种方法,终于发现原来是有学名的。(●’◡’●)
这里介绍一种使用宏定义函数来创建工厂函数的方法,借鉴了cocos的宏。
1、首先,我们要避免创建一个不能实例化的抽象父类,除去用RTTI,使用类id,我们还可以用如下方案:
template <typename T>
struct IsAbstract
{
typedef char SmallType;
typedef int LargeType;
template <typename U>
static char Test(U(*)[1]);
template <typename U>
static int Test(...);
const static bool Result = sizeof(Test<T>(NULL)) == sizeof(LargeType);
};
这是笔者在知乎上找到的一个例子,也就是用了c++数组对象不能是抽象类这一点,自动匹配重载函数的时候会匹配到使用任何参数的Test(…),然后自然就返回一个char的长度。
然后我们来看宏定义函数,有两个,一个是添加create函数,一个是用于工厂模式创建类:
#define CREATE_FISH(__FISHTYPE__) ([](){ return __FISHTYPE__::create();})
//检查是否是完整类(避免抽象类被实现从而导致错误),然后使用工厂函数创建类
#define ADD_CREATE(__TYPE__) \
static __TYPE__* create() \
{ \
if (IsAbstract<__TYPE__>::Result) \
{ \
assert(0 && "abstract class"); \
return NULL; \
} \
__TYPE__ *pRet = new(std::nothrow) __TYPE__(); \
if (pRet) \
{ \
return pRet; \
} \
else \
{ \
delete pRet; \
pRet = NULL; \
return NULL; \
} \
}
由于宏定义是在编译前的字符串替换,所以最好每句都加上“\”符号,然后有必要的话最外面加括号。
ok,一个小技巧,感觉比写virtual函数爽多了!~w_w~
原文链接:https://blog.csdn.net/qq_22984991/article/details/51520412
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)