IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> c++ Factor泛型编程示例 -> 正文阅读

[C++知识库]c++ Factor泛型编程示例

c++ Factor泛型编程示例

c++ 泛型编程 之Factor (c++ 设计新思维)
一.概述
泛化仿函数是将“请求(函数)封装起来”,存储与对象中,该对象是具有“value语义”的,因此支持拷贝,赋值和作为函数参数来传值(pass by value)。通过该对象可间接的处理封装的请求,类似于boost 中的function功能。本实现采用的是《Modern C++ Design》中的方案。更详尽的说,具有以下特点:

  1. 可封装任何处理请求,可接受函数指针,成员函数指针,仿函数,甚至其它泛化仿函数。
  2. 具备型别安全性,不会将错误的型别匹配到错误的函数上。
  3. 一种带有“value语义的对象”。
    先介绍下C++中的可调用体:
  4. C风格的函数(C like function): void fun();
  5. C风格的函数指针(C like pointto function): void (*pFun)();
  6. 函数引用(reference to function),其行为本质上和const pointer to function类似。
  7. 仿函数(functor),类中自定义了operator () 的对象。
  8. Operator.*和operator->*的施行结果
  9. 构造函数
    在上述的任一项,可以在右侧添加一对圆括号(),在里头放入一组合适的参数。
    先来讨论这样一个问题,既然想把函数请求封装到对象中,函数的参数如何确定?这里使用typelist(这是一个型别集,包含型别列表)。这里就可以把typelist作为HTFunctor的一个模板参数,包含所要封装函数的参数型别信息。下面就先介绍下typelist实作。
    二.HTTypeList
    [cpp]
  10. template <class T, class U>
  11. struct HTTypeList
  12. {
  13.  typedef T Head;  
    
  14.  typedef U Tail;  
    
  15. };
    这是typelist的基本实作(只需两个类型),现在问题是如何把n个类型连成链表。看下面这个例子就明白了
  16. typedef HTTypeList<char, HTTypeList<int, int> >
    (利用模板参数推导,编译器自动产生,而不是运行期哦),这样两个以上的参数都解决了。
    现在问题如何定义一个参数的typelist。方法是,第二个模板参数设为NullType(空类型),这样每个typelist都以NullType结尾,相当于C字符串的\0功能。看NullType的实作:
    [cpp]
  17. class HTNullType {};
    接着就要生产typelist了(一个参数,两个参数,三个参数……)。这里用到宏,暂且定义4个typelist。
    [cpp]
  18. #define TYPELIST_1(T1) UTIL::HTTypeList<T1, UTIL::HTNullType>
  19. #define TYPELIST_2(T1, T2) UTIL::HTTypeList<T1, TYPELIST_1(T2) >
  20. #define TYPELIST_3(T1, T2, T3) UTIL::HTTypeList<T1, TYPELIST_2(T2, T3) >
  21. #define TYPELIST_4(T1, T2, T3, T4) UTIL::HTTypeList<T1, TYPELIST_3(T2, T3, T4) >
    另外要解决的问题,函数参数该是值类型(内部内型),还是引用类型(对于对象)。选择合适的类型显然能提高程序速度,肯定不想传递大对象参数时要额外拷贝。接下来这个东西就要登场了——( HTTypeTraits )
    三:HTTypeTraits
    可用于“编译期根据型别作判断”的泛型技术。大家也可参看boost中的type traits。
    [cpp]
  22. // 判断T及U是否标示同一个类型
  23. template <typename T, typename U>
  24. struct HTIsSameType
  25. {
  26. private:
  27.  template<typename>  
    
  28.  struct In   
    
  29.  { enum { value = false }; };  
    
  30. template<>  
    
  31. struct In<T>  
    
  32. { enum { value = true };  };  
    
  33. public:
  34. enum { value = In<U>::value };  
    
  35. };
    [cpp]
  36. // 依flag选择两个类型中的一个,true为T,false为U
  37. template <bool flag, typename T, typename U>
  38. struct HTSelect
  39. {
  40. private:
  41.  template<bool>  
    
  42.  struct In   
    
  43.  { typedef T Result; };  
    
  44. template<>  
    
  45. struct In<false>  
    
  46. { typedef U Result; };  
    
  47. public:
  48. typedef typename In<flag>::Result Result;  
    
  49. };
    [cpp]
  50. // 编译期bool型
  51. typedef char HTYes;
  52. struct HTNo { char padding[8]; };
  53. // 型别映射为型别,用于模板函数的偏特化,C++标准模板函数不能偏特化
  54. template
  55. struct HTType2Type { typedef T Type; };
  56. // 判断T是否为类
  57. template
  58. struct HTIsClass
  59. {
  60. // U为类的话,会具现化此重载函数,因为参数为函数指针,即指向成员的函数指针  
    
  61. template <typename U> static HTYes IsClassTest(void(U::*)(void));  
    
  62. // U为非类,会具现化此重载函数  
    
  63. // C++标准:只有当其它所有的重载版本都不能匹配时,具有任意参数列表的重载版本才会被匹配  
    
  64. template <typename U> static HTNo IsClassTest(...);  
    
  65. // 对于sizeof,表达式不会被真正求值,编译器只推导出表达式的返回结果的型别,因此只需函数的声明即可  
    
  66. static const bool value = sizeof(IsClassTest<T>(0)) = sizeof(HTYes);  
    
  67. };
  68. // 判断T是否为引用类型
  69. template
  70. struct HTIsReference
  71. {
  72. template <typename U> static HTYes IsReference(HTType2Type<U&>);  
    
  73. template <typename U> static HTNo IsReference(...);  
    
  74. static const bool value= sizeof(IsReference(HTType2Type<T>())) == sizeof(HTYes);  
    
  75. };
  76. template
  77. class HTTypeTraits
  78. {
  79. public:
  80. enum {   
    
  81.     isVoid =   
    
  82.     HTIsSameType<T, void>::value          ||  
    
  83.     HTIsSameType<T, const void>::value    ||  
    
  84.     HTIsSameType<T, volatile void>::value ||  
    
  85.     HTIsSameType<T, const volatile void>::value  
    
  86. };  
    
  87. enum { isReference = HTIsReference<T>::value };  
    
  88. private:
  89. template<bool IsRef>  
    
  90. struct AdjReference  
    
  91. {  
    
  92.     template<typename U>  
    
  93.     struct In { typedef U const & Result; };  
    
  94. };  
    
  95. template<>  
    
  96. struct AdjReference<true>  
    
  97. {  
    
  98.     template<typename U>  
    
  99.     struct In { typedef U Result; };  
    
  100. };  
    
  101. typedef typename AdjReference<isReference || isVoid>::  
    
  102.     template In<T>::Result AdjType;  
    
  103. // 正确的选择函数参数的类型  
    
  104. // 对于精巧型(有构造函数和析构函数额外调用)采用引用传参数,对于纯量型(数值型别,枚举型别,指针,指向成员的指针)采用直接传值  
    
  105. typedef typename HTSelect<HTIsClass<T>::value, AdjType, T>::Result ParmType;  
    
  106. };
    四:HTFunctor
    HTTypeList及HTTypeTraits提供我们强大的功能。这让我们实作HTFunctor更加的方便。下面直接看代码。
    [cpp]
  107. // Functor对象明显是个小对象,这里采用小对象分配器
  108. // 使用了Command模式及IMPL模式
  109. template
  110. struct HTFunctorImplBase : public HTSmallObject<>
  111. {
  112.  typedef R   ResultType;  
    
  113.  typedef HTEmptyType Parm1;  
    
  114.  typedef HTEmptyType Parm2;  
    
  115. };
  116. template <typename R, class TList, class ObjClass>
  117. struct HTFunctorImpl;
  118. // 无参数版本
  119. template <typename R, class ObjClass>
  120. struct HTFunctorImpl<R, HTNullType, ObjClass> : public HTFunctorImplBase
  121. {
  122. typedef R       ResultType;  
    
  123. virtual ResultType operator()(ObjClass* pObj) = 0;  
    
  124. virtual HTFunctorImpl* Clone() const = 0;  
    
  125. virtual ~HTFunctorImpl() {}  
    
  126. };
  127. // 一个参数版本
  128. template <typename R, typename P1, class ObjClass>
  129. struct HTFunctorImpl<R, TYPELIST_1(P1), ObjClass> : public HTFunctorImplBase
  130. {
  131. typedef R       ResultType;  
    
  132. typedef typename HTTypeTraits<P1>::ParmType   Parm1;  
    
  133. virtual ResultType operator()(Parm1, ObjClass* pObj) = 0;  
    
  134. virtual HTFunctorImpl* Clone() const = 0;  
    
  135. virtual ~HTFunctorImpl() {}  
    
  136. };
  137. // 两个参数版本
  138. template <typename R, typename P1, typename P2, class ObjClass>
  139. struct HTFunctorImpl<R, TYPELIST_2(P1, P2), ObjClass> : public HTFunctorImplBase
  140. {
  141. typedef R       ResultType;  
    
  142. typedef typename HTTypeTraits<P1>::ParmType   Parm1;  
    
  143. typedef typename HTTypeTraits<P2>::ParmType Parm2;  
    
  144. virtual ResultType operator()(Parm1, Parm2, ObjClass* pObj) = 0;  
    
  145. virtual HTFunctorImpl* Clone() const = 0;  
    
  146. virtual ~HTFunctorImpl() {}  
    
  147. };
  148. // 可调用体(即封装的处理函数)为仿函数
  149. template <class ParentFunctor, typename Fun, class ObjClass>
  150. class HTFunctorHandler :
  151. public HTFunctorImpl  
    
  152.             <   
    
  153.             typename ParentFunctor::ResultType,  
    
  154.             typename ParentFunctor::ParmList,  
    
  155.             ObjClass  
    
  156.             >  
    
  157. {
  158. typedef typename ParentFunctor::Impl    Base;  
    
  159. public:
  160. typedef typename Base::ResultType ResultType;  
    
  161. typedef typename Base::Parm1 Parm1;  
    
  162. typedef typename Base::Parm1 Parm2;  
    
  163. HTFunctorHandler(const Fun& fun) : m_fun(fun) {}  
    
  164. HTFunctorHandler* Clone() const { return new HTFunctorHandler(*this); }  
    
  165. ResultType operator()(ObjClass* pObj)   
    
  166. { return m_fun(); }  
    
  167. ResultType operator()(Parm1 p1, ObjClass* pObj)  
    
  168. { return m_fun(p1); }  
    
  169. ResultType operator()(Parm1 p1, Parm2 p2, ObjClass* pObj)  
    
  170. { return m_fun(p1, p2); }  
    
  171. private:
  172. Fun m_fun;  
    
  173. };
  174. // 可调用体(即封装的处理函数)为类成员函数,调用需传递对象指针
  175. template <class ParentFunctor, typename Fun, class ObjClass>
  176. class HTMemFunHandler :
  177. public HTFunctorImpl  
    
  178.             <   
    
  179.             typename ParentFunctor::ResultType,  
    
  180.             typename ParentFunctor::ParmList,  
    
  181.             ObjClass  
    
  182.             >  
    
  183. {
  184. typedef typename ParentFunctor::Impl    Base;  
    
  185. public:
  186. typedef typename Base::ResultType ResultType;  
    
  187. typedef typename Base::Parm1 Parm1;  
    
  188. typedef typename Base::Parm1 Parm2;  
    
  189.    HTMemFunHandler(const Fun& fun) : m_fun(fun) {}  
    
  190.    HTMemFunHandler* Clone() const { return new HTMemFunHandler(*this); }  
    
  191.    ResultType operator()(ObjClass* pObj)   
    
  192.    { return (pObj->*m_fun)(); }  
    
  193.    ResultType operator()(Parm1 p1, ObjClass* pObj)   
    
  194.    { return (pObj->*m_fun)(p1); }  
    
  195.    ResultType operator()(Parm1 p1, Parm2 p2, ObjClass* pObj)  
    
  196.    { return (pObj->*m_fun)(p1, p2); }  
    
  197. private:
  198.    Fun m_fun;  
    
  199. };
  200. // HTFunctor实现体
  201. template <typename R, class TList = YKNullType, class ObjClass = YKEmptyType>
  202. class HTFunctor
  203. {
  204.    typedef HTFunctorImpl<R, TList, ObjClass> Impl;  
    
  205. public:
  206.    typedef R       ResultType;  
    
  207.    typedef TList   ParmList;  
    
  208.    typedef typename Impl::Parm1 Parm1;  
    
  209.    typedef typename Impl::Parm2 Parm2;  
    
  210.    HTFunctor() : m_spImpl() {}  
    
  211.    HTFunctor(const HTFunctor& rhs) : m_spImpl(rhs.m_spImpl->Clone()) {}  
    
  212.    explicit HTFunctor(std::auto_ptr<Impl> spImpl) : m_spImpl(spImpl) {}  
    
  213.    HTFunctor& operator=(const HTFunctor& rhs)  
    
  214.    {  
    
  215.        HTFunctor copy(rhs);  
    
  216.        Impl* p = m_spImpl.release();  
    
  217.        m_spImpl.reset(copy.m_spImpl.release());  
    
  218.        copy.m_spImpl.reset(p);  
    
  219.        return *this;  
    
  220.    }  
    
  221.    template <typename Fun>  
    
  222.    HTFunctor(Fun fun)  
    
  223.        : m_spImpl(new   
    
  224.        HTSelect<  
    
  225.            HTIsSameType<ObjClass, HTEmptyType>::value,   
    
  226.            HTFunctorHandler<HTFunctor, Fun, ObjClass>,   
    
  227.            HTMemFunHandler<HTFunctor, Fun, ObjClass> >::Result(fun))  
    
  228.    {}  
    
  229.    ResultType operator()(ObjClass* pObj = HT_NULL) {  
    
  230.        return (*m_spImpl)(pObj);  
    
  231.    }  
    
  232.    ResultType operator()(Parm1 p1, ObjClass* pObj = HT_NULL) {  
    
  233.        return (*m_spImpl)(p1, pObj);  
    
  234.    }  
    
  235.    ResultType operator()(Parm1 p1, Parm2 p2, ObjClass* pObj = HT_NULL) {  
    
  236.        return (*m_spImpl)(p1, p2, pObj);  
    
  237.    }  
    
  238. private:
  239.    std::auto_ptr<Impl> m_spImpl;  
    
  240. };
    五.Krypton Factor C++
    #include
    #include
    #include
    #include
    using namespace std;
    int cnt;
    int n,L;
    int ans;
    int S[100001];
    int dfs(int cur)
    {
    if(cnt++n){
    for(int i=0;i<cur;i++){if(i%4
    0&&i&&i<cur&&i%64!=0)cout<<" “;if(i&&i%64==0&&i<cur)cout<<endl;printf(”%c",‘A’+S[i]);ans++;}
    printf("\n");
    return 0;
    }
    for(int i=0;i<L;i++)
    {
    S[cur]=i;
    int ok=1;
    for(int j=1;j*2<=cur+1;j++)
    {
    int equal_=1;
    for(int k=0;k<j;k++)
    if(S[cur-k]!=S[cur-k-j]){equal_=0;break;}
    if(equal_){ok=0;break;}
    }
    if(ok)if(!dfs(cur+1))return 0;
    }
    return 1;
    }
    int main()
    {
    while(cin>>n>>L&&n&&L){
    ans=0;
    cnt=0;
    dfs(0);
    cout<<ans<<endl;
    }
    return 0;
    }
    六.C++泛型编程与设计模式( 函数内部类 )

class Interface {
virtual void func() =0;
};

template<class T, class P>
Interface *makeAdapter(T tt, P pp) {
int a = 10;
static int count = 10;
class Local : public Interface {
public:
Local(const T &t, const P &p) : p§, t(t) {
// cout << a << endl;
cout << count << endl;
}
virtual void func() {
}
private:
P p;
T t;
static int k;
};
return new Local(tt,pp);
};
这个例子很简单,开始定义了一个接口,然后定义了一个方法,该方法返回一个Interface的指针,在makeAdapter方法中,定义了Local类,然后继承自接口Interface,因为这里的Local是个类,是个局部的,所以无法被外部代码所使用,这就说明了,局部类的使用限制性还是挺大的:

  1. 要么就在方法内部使用。
  2. 如果要在外部使用,不论是直接返回,还是存在其它的包裹方式,都必须继承已经存在的接口或者是基类。
    在这里插入图片描述

局部类这种独特的特性,非常类似于其他语言中的final类,如说PHP,JAVA,因为他是局部的,所以无法被外部继承。如果不希望类被继承的话,局部类是个不错的方法。

参考链接:
https://blog.csdn.net/zhuyingqingfen/article/details/10124527
https://blog.csdn.net/Zero_979/article/details/81205702
https://blog.csdn.net/oKanJianLiao/article/details/80711167

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-18 11:01:39  更:2021-11-18 11:03:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:16:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码