Command設計模式1

2014-11-06 星期四 21:54:23 

隨便記錄,本文是loki command模式的簡化版本。雖然是簡化的,但是泛化的精髓還是原汁原味的。我們在泛化編程時,對模板形參可以用具現的眼光來看待。泛化編程,具現理解。

1、代碼(.h)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#include <algorithm>
#include <iostream>
#include <vector>
#include <iterator>
#include <map>
#include <memory>
#include <typeinfo>
#include <assert.h>
#include <stdio.h>
 
#ifndef __MYFUNCTOR_H__
#define __MYFUNCTOR_H__
 
class NullType {};
 
template <class T, class U>
struct Typelist
{
   typedef T Head;
   typedef U Tail;
};
 
#define TYPELIST_1(T1)          Typelist<T1, NullType>
#define TYPELIST_2(T1, T2)      Typelist<T1, TYPELIST_1(T2) >
#define TYPELIST_3(T1, T2, T3)  Typelist<T1, TYPELIST_2(T2, T3) >
 
////////////////////////////////////////////////////////////////////////////////
// class template TypeAtNonStrict
// Finds the type at a given index in a typelist
// Invocations (TList is a typelist and index is a compile-time integral
//     constant):
// a) TypeAt<TList, index>::Result
// returns the type in position 'index' in TList, or NullType if index is
//     out-of-bounds
// b) TypeAt<TList, index, D>::Result
// returns the type in position 'index' in TList, or D if index is out-of-bounds
////////////////////////////////////////////////////////////////////////////////
 
template <class TList, unsigned int index,
    typename DefaultType = NullType>
struct TypeAtNonStrict
{
    typedef DefaultType Result;
};
 
template <class Head, class Tail, typename DefaultType>
struct TypeAtNonStrict<Typelist<Head, Tail>, 0, DefaultType>
{
    typedef Head Result;
};
 
template <class Head, class Tail, unsigned int i, typename DefaultType>
struct TypeAtNonStrict<Typelist<Head, Tail>, i, DefaultType>
{
    typedef typename
        TypeAtNonStrict<Tail, i - 1, DefaultType>::Result Result;
};
 
 
template <typename R, class TList>
class FunctorImpl;
 
template <typename R>
class FunctorImpl<R, NullType>
{
public:
    typedef R   ResultType;
    virtual ResultType operator()() = 0;
    virtual FunctorImpl *Clone() const = 0;
    virtual ~FunctorImpl(){}
};
 
template <typename R, typename P1>
class FunctorImpl<R, TYPELIST_1(P1) >
{
public:
    typedef R   ResultType;
    //typedef typename TypeTraits<P1>::ParameterType Parm1;  
    typedef P1  Parm1;
 
    virtual ResultType operator()(Parm1) = 0;
    virtual FunctorImpl *Clone() const = 0;
    virtual ~FunctorImpl(){}
};
 
template <typename R, typename P1, typename P2>
class FunctorImpl<R, TYPELIST_2(P1, P2) >
{
public:
    typedef R   ResultType;
    typedef P1  Parm1;
    typedef P2  Parm2;
    FunctorImpl()
    {
        printf("line %d, FunctorImpl::%s\n", __LINE__, __func__);
    }
    virtual ResultType operator()(Parm1, Parm2) = 0;
    virtual FunctorImpl *Clone() const = 0;
    virtual ~FunctorImpl(){}
};
 
 
template <class ParentFunctor, typename Fun>
class FunctorHandler
#if 0
    :public FunctorImpl
    <
        typename ParentFunctor::ResultType,
        typename ParentFunctor::ParamList
    >
#else
    :public ParentFunctor::Impl
#endif
{
public:
    typedef typename ParentFunctor::Parm1 Parm1;
    typedef typename ParentFunctor::Parm2 Parm2;   
    typedef typename ParentFunctor::ResultType ResultType;
 
    FunctorHandler(const Fun& fun):fun_(fun)
    {
        printf("line %d, FunctorHandler::%s\n", __LINE__, __func__);
    }
    FunctorHandler *Clone() const
    {
        return new FunctorHandler(*this);
    }
 
    ResultType operator()(Parm1 p1)
    {
        return fun_(p1);
    }
 
    ResultType operator()(Parm1 p1, Parm2 p2)
    {
        printf("line %d, FunctorHandler::%s\n", __LINE__, __func__);
        return fun_(p1, p2);
    }
     
private:
    Fun fun_;
};
 
 
//Functor
template <typename R, class TList>
class Functor;
 
#define IMPL_IN_CLASS
 
template <typename R, class TList>
class Functor
{
public:
    typedef R ResultType;
    typedef TList ParamList;
 
    // Handy type definitions for the body type
    typedef FunctorImpl<R, TList> Impl;
    //typedef typename Impl::Parm1 Parm1;
    //typedef typename Impl::Parm2 Parm2;
    typedef typename
        TypeAtNonStrict<TList, 0, NullType>::Result Parm1;
 
    typedef typename
        TypeAtNonStrict<TList, 1, NullType>::Result Parm2;
 
public:
        Functor() : spImpl_(0)
        {
            printf("line %d, Functor::%s, num %d\n", __LINE__, __func__, 2);
        }
         
        Functor(const Functor& rhs) : spImpl_(Impl::Clone())
        {}
         
        explicit Functor(std::auto_ptr<Impl> spImpl) : spImpl_(spImpl)
        {}
         
        Functor& operator=(const Functor&);
 
#ifdef  IMPL_IN_CLASS
 
        template<typename Fun>
        Functor(const Fun& fun)
        :spImpl_(new FunctorHandler<Functor, Fun>(fun))
        {
            printf("line %d, Functor::%s\n", __LINE__, __func__);
        }
#else
 
        template<class Fun>
        Functor(const Fun& fun);
#endif
 
private:
public:
    // operator() implementations for up to 2 arguments
    ResultType operator()() const
    {
        return (*spImpl_)();
    }
 
    ResultType operator()(Parm1 p1) const
    {
        return (*spImpl_)(p1);
    }
 
    ResultType operator()(Parm1 p1, Parm2 p2) const
    {
        printf("line %d, Functor::%s\n", __LINE__, __func__);
        return (*spImpl_)(p1, p2);
    }
 
private:
    std::auto_ptr<Impl> spImpl_;
         
};
 
 
#endif


2、代碼(.cpp)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include "myfunctor.h"
 
#ifndef IMPL_IN_CLASS
//位於class本體之外的member template定義式
//第一組template<typename R, class Tlist>用於class template Functor
//第二組template<class Fun>用於構造函數的參數
template<typename R, class Tlist>
template<typename Fun>
Functor<R, Tlist>::Functor(const Fun& fun)
:spImpl_(new FunctorHandler<Functor, Fun>(fun))
{
    printf("line %d, Functor::%s, num %d\n", __LINE__, __func__, 2);
}
#endif
 
struct TestFunctor
{
    void operator()(int p1, double p2)
    {
        printf("TestFunctor::operator(%d, %f) called\n", p1, p2);
    }
};
 
int main(int argc, char* argv[])
{
    TestFunctor f;
 
#if 0
    Functor< double, TYPELIST_2(int double) > myFunctor;
    double result = myFunctor(4, 4.5);
#endif
 
    Functor< void, TYPELIST_2(int double) > cmd(f);
    cmd(5, 5.5);
 
    //error,operator() is not invalid because FunctorImpl< double, TYPELIST_2(int , double) >
    //dose not define one
    //double result1 = myFunctor();
 
    return 0;
}



發佈了66 篇原創文章 · 獲贊 8 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章