gpt4 book ai didi

c++ - 重构指向某种形式模板的函数指针

转载 作者:太空宇宙 更新时间:2023-11-04 12:27:02 25 4
gpt4 key购买 nike

请耐心等待我转储以下简化代码:(我将在下面描述问题。)

class CMyClass
{
...
private:
HRESULT ReadAlpha(PROPVARIANT* pPropVariant, SomeLib::Base *b);
HRESULT ReadBeta(PROPVARIANT* pPropVariant, SomeLib::Base *b);

typedef HRESULT (CMyClass::*ReadSignature)(PROPVARIANT* pPropVariant, SomeLib::Base *b);

HRESULT TryFormats(ReadSignature ReadFormat, PROPVARIANT* pPropVariant);
};


inline HRESULT CMyClass::ReadAlpha(PROPVARIANT* pPropVariant, SomeLib::Base *b)
{
if (b)
{
// got a valid Base. Handle generic stuff here.
SetStuff(pPropVariant, b->someInt);
return S_OK;
}

return (b != NULL) ? 0 : -1;
}

inline HRESULT CMyClass::ReadBeta(PROPVARIANT* pPropVariant, SomeLib::Base *b)
{
if (b)
{
SomeLib::FormatA *fa;
SomeLib::FormatB *fb;

if ( fa = dynamic_cast<SomeLib::FormatA*>( b ) )
{
// specific code for FormatA
SetStuff(pPropVariant, fa->getVersion());
return S_OK;
}
else if ( fb = dynamic_cast<SomeLib::FormatB*>( b ) )
{
// specific code for FormatB
SetStuff(pPropVariant, fb->valueForB);
return S_OK;
}
}

return (b != NULL) ? 0 : -1;
}

inline HRESULT CMyClass::TryFormats(ReadSignature ReadFormat, PROPVARIANT* pPropVariant)
{
HRESULT hr;
if (FAILED(hr = (this->*ReadFormat)(pPropVariant, _pFile->formatA())))
if (FAILED(hr = (this->*ReadFormat)(pPropVariant, _pFile->formatC())))
hr = (this->*ReadFormat)(pPropVariant, _pFile->formatD());

return hr;
}

我最终像这样调用这段代码:

hr = TryFormats(&CMyClass::ReadAlpha, pPropVar);

现在...问题是这太笼统和受限了,尤其是现在我正在尝试重构此代码以用于其他一些项目。所以,这意味着我想放置 ReadXxx另一个源文件中的代码并以某种方式滥用模板。 TryFormats留在类里面,因为不同的类(class)有不同的阅读格式。

由于 dynamic_cast<Derived*>,我目前的方法注定会失败Base 中没有的功能需要类,并且由于我可能需要在一节课中阅读多达 5 种不同的格式,所以我真的不想拖入我一开始不需要的格式。 (例如,参见上面的 CMyClass 不支持 SomeLib::FormatB ,但 ReadBeta() 需要支持它,从而强制编译器编译所有相关信息。)总共,我有大约 10 种不同的格式像这样'支持'。

如何正确重构这段代码?我不想重写 Base每个后代的功能,我也不想将派生的特定信息放入只接受 Base 的函数中.

我已经尝试了一些东西,但我设法从我的编译器中挤出的是错误的彩虹。为了不让这里的人对我的尝试感到困惑,我想我会给出我的(简化的)原始工作代码,并让专家们就如何做到这一点得出他们自己的结论。实际上,其中大约有 50 个 ReadXxx功能,但它们要么遵循 ReadAlpha 的一般结构或 ReadBeta以上功能。因此,如果有人可以告诉我如何执行这些操作,我就可以毫无问题地转换我的实际代码。 (我想我也需要更改 TryFormats() 定义,这也没问题 - 我只是希望有人能告诉我如何正确重构上述示例。)

谢谢,对于这个很长很长的问题,我深表歉意。

最佳答案

好吧,我之前的visitor方法已经成为历史。我将向您发布您可以使用的小型工作程序的完整文本。假设

_pFile->formatA()
_pFile->formatC()
_pFile->formatD()

全部声明为

FormatA* formatA()
FormatC* formatC()
FormatD* formatD()

换句话说,返回类型在编译时是已知的,这种模板化的方法可能适合你。而且它既不涉及函数指针也不涉及动态向下转型

//////////////////////////////////////////////////////////////////
// this section is for testing
class Base
{
public:
void ExecuteBase()
{
cout << "Executing Base" << endl;
}
};

class FormatA : public Base
{
public:
void ExecuteAAlpha()
{
cout << "Executing A Alpha" << endl;
}

void ExecuteABeta()
{
cout << "Executing A Beta" << endl;
}
};

class FormatB : public Base
{
public:
void ExecuteBAlpha()
{
cout << "Executing B Alpha" << endl;
}

void ExecuteBBeta()
{
cout << "Executing B Beta" << endl;
}
};

FormatA* GetFormatA()
{
static FormatA cl;
return &cl;
}

FormatB* GetFormatB()
{
static FormatB cl;
return &cl;
}
//////////////////////////////////////////////////////////////////




//////////////////////////////////////////////////////////////////
// now begins real code
struct AlphaReader {};
struct BetaReader {};
template <typename READER_TYPE> struct TypeConverter {};


class MyClass
{
public:
template <typename READER_TYPE>
int TryFormats(const READER_TYPE&)
{
TryFormatsImplementation(TypeConverter<READER_TYPE>(), GetFormatA());
TryFormatsImplementation(TypeConverter<READER_TYPE>(), GetFormatB());

return 0;
}

private:
int TryFormatsImplementation(const TypeConverter<AlphaReader>&, Base* pFormat)
{
// here you will call you ReadAlpha which requires Base only
// code below is for testing

cout << "Executing Alpha Reader for Base" <<endl;
pFormat->ExecuteBase();
return 1;
}

int TryFormatsImplementation(const TypeConverter<BetaReader>&, FormatA* pFormat)
{
// here you will call you ReadBeta for FromatA,
// code below is for testing

cout << "Executing Beta Reader for FormatA" <<endl;
pFormat->ExecuteABeta();
return 3;
}

int TryFormatsImplementation(const TypeConverter<BetaReader>&, FormatB* pFormat)
{
// here you will call you ReadBeta for FromatB,
// code below is for testing

cout << "Executing Beta Reader for FormatB" <<endl;
pFormat->ExecuteBBeta();
return 4;
}
};


int main()
{
MyClass cl;

cl.TryFormats(AlphaReader());
cl.TryFormats(BetaReader());

cin.get();
}

运行此程序后,我得到以下正确输出:

Executing Alpha Reader for Base
Executing Base
Executing Alpha Reader for Base
Executing Base
Executing Beta Reader for FormatA
Executing A Beta
Executing Beta Reader for FormatB
Executing B Beta

关于c++ - 重构指向某种形式模板的函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1770808/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com