处理重复的Prolog/正文/Epilog模式的建议方法
Suggested Approach in dealing with repetitive Prolog / Body / Epilog Pattern
我有一个场景,其中我有很多具有以下模式的函数
RETURN_TYPE FOO(
TYPE PARM1,
TYPE PARM2)
{
PROLOG(PARM1, PARM2);
//FOO_BODY
EPILOG(PARM1, PARM2);
}
考虑遵循上述模式的示例函数
SQLRETURN SQLGetInfo(
SQLHDBC ConnectionHandle,
SQLUSMALLINT InfoType,
SQLPOINTER InfoValuePtr,
SQLSMALLINT BufferLength,
SQLSMALLINT * StringLengthPtr)
{
// ******** Prolog(InfoValuePtr, BufferLength) *************
CComSafeArray<BYTE> _InfoValuePtr(BufferLength);
LPBYTE pData;
// **********************************************************
SQLRETURN rc = p->SQLGetInfo(
reinterpret_cast<PSSQLHSTMT>(ConnectionHandle),
InfoType,
_InfoValuePtr,
BufferLength,
StringLengthPtr);
// ******** Epilog(InfoValuePtr) ******************************
::SafeArrayAccessData(_InfoValuePtr, reinterpret_cast<void **>(&pData));
memcpy_s(InfoValuePtr, BufferLength, pData, _InfoValuePtr.GetCount());
::SafeArrayUnaccessData(_InfoValuePtr);
return rc;
// *************************************************************
}
我的困境是,我有点不舒服地一次又一次地重复相同的代码模式,这在开发过程中容易出错并且代码膨胀。即使在明天,改变一些东西也意味着一丝不苟地改变每一个事件,以与变化保持一致。
处理模式的建议方法/最佳实践是什么? Macros
, Templates
注意我们仍然没有使用boost,添加boost只是为了解决这个问题可能不是一个选择
@Abhijit:我自己的直觉也倾向于模板。 但是,你上面的例子看起来并不像你上面给出的简化模型。 如果您确实有大量看起来相同的函数,除了某些中间部分,那么模板可以清理它。 使模板参数成为指向挂钩到 prolog 和 epilog 的函数的函数指针。 这几乎是咖喱的变体,但不完全是。
在不完全理解上面的示例的情况下,下面是如何将其转换为使用模板的草图。 由于示例的主体只是一个函数调用,因此此转换不会真正公开模式的强大功能。 但是,它应该希望给出一个想法。
// Define the "body function" in a typedef, for sanity's sake
typedef SQLRETURN
(*SQLGetInfoFunc)(
PSSQLHSTMT,
SQLUSMALLINT,
CComSafeArray<BYTE>,
SQLSMALLINT,
SQLSMALLINT*
);
// Templated version of SQLGetInfo
template <SQLGetInfoFunc *F>
SQLRETURN SQLGetInfo(
SQLHDBC ConnectionHandle,
SQLUSMALLINT InfoType,
SQLPOINTER InfoValuePtr,
SQLSMALLINT BufferLength,
SQLSMALLINT * StringLengthPtr)
{
// ******** Prolog(InfoValuePtr, BufferLength) *************
CComSafeArray<BYTE> _InfoValuePtr(BufferLength);
LPBYTE pData;
// **********************************************************
SQLRETURN rc = F(
reinterpret_cast<PSSQLHSTMT>(ConnectionHandle),
InfoType,
_InfoValuePtr,
BufferLength,
StringLengthPtr);
// ******** Epilog(InfoValuePtr) ******************************
::SafeArrayAccessData(_InfoValuePtr, reinterpret_cast<void **>(&pData));
memcpy_s(InfoValuePtr, BufferLength, pData, _InfoValuePtr.GetCount());
::SafeArrayUnaccessData(_InfoValuePtr);
return rc;
// *************************************************************
}
在此示例中,F
是将作为模板参数提供的函数指针。 也就是说,我注意到您的原始示例使用了p->SQLGetInfo
,但我没有看到p
在哪里定义。
为了提供一个显示基本模式的完整示例,请考虑以下代码:
#include <iostream>
typedef int (*fxn)(int);
inline int fred(int x)
{
return x + 100;
}
inline int barney(int x)
{
return x + 200;
}
template <fxn F>
void apply_to_array(int *array, int len)
{
for (int i = 0; i < len; i++)
array[i] = F(array[i]);
}
using namespace std;
void print_array(int *array, int len)
{
for (int i = 0; i < len; i++)
cout << " " << array[i];
cout << endl;
}
int af[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int ab[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int main(void)
{
cout << "Before: af = ";
print_array(af, 10);
apply_to_array<fred>(af, 10);
cout << "After apply_to_array<fred>(af): af = ";
print_array(af, 10);
cout << "Before: ab = ";
print_array(ab, 10);
apply_to_array<barney>(ab, 10);
cout << "After apply_to_array<barney>(ab): ab = ";
print_array(ab, 10);
return 0;
}
它输出以下内容:
Before: af = 1 2 3 4 5 6 7 8 9 10
After apply_to_array<fred>(af): af = 101 102 103 104 105 106 107 108 109 110
Before: ab = 1 2 3 4 5 6 7 8 9 10
After apply_to_array<barney>(ab): ab = 201 202 203 204 205 206 207 208 209 210
相关文章:
- c++方法参数只能在linux的发布模式下自行更改
- 使用模板而不是虚拟方法的管道模式
- 只需要知道我在c ++中打印模式的方式是否有效,或者有另一种方法可以有效地做到这一点
- 在C++中创建观察器设计模式的好方法
- 工厂方法模式使用继承而抽象工厂模式使用组合如何
- 是否有可以处理方法调用依赖关系的设计模式?
- 设计模式中对象中的过程(方法和操作)的状态
- 用各种语言表示模式的方法
- 在数组中查找模式的最有效方法?
- 设计模式的工厂替代方法:具有不同构造函数的类
- C++,在阻塞模式下从套接字读取所有可用字节的最佳方法
- 正确的方法或设计模式,以简化类中的“operatorX”函数,以按给定顺序比较相同类型的属性
- 返回不同类型/类的方法的设计模式
- 如何将策略模式与派生类中的其他方法一起使用
- 类型擦除和一种模板方法模式
- 对不同的参数使用工厂方法模式
- 一种在 Mac 上强制关闭模式 QFileDialog 的方法
- dlopen、工厂模式和虚拟方法表
- 工厂模式和std::绑定方法
- 找到数据集C 模式的更好方法