gpt4 book ai didi

C++:设计、函数模板覆盖和缺乏多态性

转载 作者:搜寻专家 更新时间:2023-10-31 01:23:26 25 4
gpt4 key购买 nike

有一个基类 A 和一个重写函数模板 Func 的派生类 B:

class A
{
A() {...};
~A() {};

template <class T>
void Func(const String &sInput, T &tResult)
{...}
};

class B : public A
{
B() {...}
~B() {};

template <class T>
void Func(const String &sInput, T &tResult)
{...}
};

(请注意,Func 是非虚拟的,因为 C++ 中缺乏对模板化虚拟函数的支持。)

现在有一个 mainprog API,M 类:

class M
{
M(boost::shared_ptr<A> &pInterfaceInput): pInterface(pInterfaceInput)
{}

template <class T>
Evaluate(const String &sInput, T &tResult)
{
pInterface->Func<T>(sInput, tResult);
}

private:
const boost::shared_ptr<A> pInterface;
};

我希望此处的 Evaluate 函数支持对基类 A 或其任何派生类(例如 B)上的函数的调用。在我重新设计 A 类和 B 类以具有模板化函数之前,编写此类时考虑到了多态性。

现在这里的问题是,如果我将基类型的共享指针传递给派生类型,那么将调用基类的 Func,而不是所指向的派生类。

我如何解决这里缺少动态多态性的问题?我考虑过将 M 类作为共享指针类型的类模板,并在构造函数中使用 static_cast 以确保该类型是基类类型 (A) 或派生类。

最好的方法是什么?我不想修改 A 类和 B 类来解决这个问题,但欢迎所有建议。

谢谢。

最佳答案

听起来像 double dispatch问题。也许这是实现 visitor pattern 的好地方?

例如创建类Evaluator ,并且对于每个 T子类 ConcreteEvaluator<T> .给AB访问 Evaluator 的方法.像这样的东西:

class Evaluator 
{
virtual void visit_A(A* object);
virtual void visit_B(B* object);
};

template <typename T>
class ConcreteEvaluator : public Evaluator
{
public:
String* input_reference;
T& result_reference;

ConcreteEvaluator(String& input_reference_,T& result_reference_) :
input_reference(input_reference_),
result_reference(result_reference_) {}

virtual void visit_A(A* object) {
object->Func(input_reference,result_reference);
}
virtual void visit_B(B* object) {
object->Func(input_reference,result_reference);
}
}

class A
{
...
virtual void apply_evaluator(Evaluator *eval) {eval->visit_A(this);}
...
}

class B
{
...
virtual void apply_evaluator(Evaluator *eval) {eval->visit_B(this);}
...
}

对于 A 的每个子类, 必须将新方法添加到 ConcreteEvaluator , 所以如果 A 这种技术效果最好的类层次结构是稳定的。对于 A 的每个子类, 它必须有一个 apply_evaluator函数定义正确。

另一方面,这可能完全矫枉过正。对于大约相同数量的工作,您总是可以支付更新费用 M::Evaluate :

class M
{
...
void Evaluate(const String& sInput, T& tResult)
{
// try to downcast to each subclass of A. Be sure to check
// sub-subclasses first
try
{
dynamic_cast<B*>(pInterface.get())->Func(sInput, tResult);
return;
}
catch (std::bad_cast& ) { }
...
// nothing worked. It must really be an A
pInterface->Func(sInput,tResult);
}
...
};

关于C++:设计、函数模板覆盖和缺乏多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1385503/

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