c++ - 可以具有不同基成员实现的类的最佳实现
问题描述
我想要一个子类Handler
来处理多个回调并将数据从一个类传输到另一个类。但是,基类B1
及其B2
成员可以有不同的实现。
下面是实现我想要的行为的方法。我认为应该有更好的方法,但无法弄清楚。
// Example program
#include <iostream>
#include <string>
template <class T>
class IBase
{
public:
IBase()
{
object = new T(*this);
};
~IBase()
{
delete object;
}
virtual void ValidateCallback()
{
};
void RxCallback()
{
object->RxCallback();
};
void Send()
{
object->Send();
};
T* object;
};
class C1
{
public:
virtual void RxCompleteCallback() = 0;
void RxParse()
{
std::cout << "Parse C1" << std::endl;
RxCompleteCallback();
};
};
class C2
{
public:
virtual void RxCompleteCallback() = 0;
void RxParse()
{
std::cout << "Parse C2" << std::endl;
RxCompleteCallback();
};
};
class B1 : public C1
{
public:
B1(IBase<B1> &handler )
{
ihandler = &handler;
};
void DoSomething()
{
std::cout << "DoSomething B1" << std::endl;
ihandler->ValidateCallback();
};
void RxCompleteCallback() override
{
std::cout << "DoSomething other than B2" << std::endl;
std::cout << "RxCompleteCallback" << std::endl;
};
void RxCallback()
{
RxParse();
};
void Send()
{
DoSomething();
};
IBase<B1> * ihandler;
};
class B2 : public C2
{
public:
B2(IBase<B2> &handler )
{
ihandler = &handler;
};
void DoSomething()
{
std::cout << "DoSomething B2" << std::endl;
ihandler->ValidateCallback();
};
void RxCompleteCallback() override
{
std::cout << "DoSomething other than B1" << std::endl;
std::cout << "RxCompleteCallback" << std::endl;
};
void RxCallback()
{
RxParse();
};
void Send()
{
DoSomething();
};
IBase<B2> * ihandler;
};
class Validate
{
public:
void CalculateValidation()
{
std::cout << "Calculate validation" << std::endl;
};
};
template <class T>
class Handler : public IBase<T>, public Validate
{
public:
void ValidateCallback() override
{
std::cout << "ValidateCallback" << std::endl;
CalculateValidation();
};
void Receive()
{
IBase<T>::RxCallback();
};
void Send()
{
IBase<T>::Send();
}
};
int main()
{
Handler<B1> handler1;
handler1.Receive();
handler1.Send();
std::cout << std::endl;
Handler<B2> handler2;
handler2.Receive();
handler2.Send();
}
输出:
Parse C1
DoSomething other than B2
RxCompleteCallback
DoSomething B1
ValidateCallback
Calculate validation
Parse C2
DoSomething other than B1
RxCompleteCallback
DoSomething B2
ValidateCallback
Calculate validation
解决方案
在 C++ 中有几种方法可以做到这一点。很难说最好的方法是什么,这取决于你将如何使用它,而且你给出的例子太简单了,无法推荐具体的方法。通常,我会说你想从 派生你的协议特定的类Handler
,而不是相反,所以你会写:
class Handler {
public:
virtual void Receive() {};
virtual void Send() {};
};
class B1: public Handler {
virtual void Receive() {
...
}
virtual void Send() {
...
}
};
int main() {
B1 handler1;
handler1.Receive();
...
}
这里的主要问题是你需要在virtual
这里使用成员函数,否则基类不知道要调用哪个派生类的实现。但它确实允许您将 aHandler *
作为参数传递给另一个函数,然后该函数将与任何派生类一起工作,而无需任何模板。
另一种选择是使用奇怪的重复模板模式,它看起来像:
template <typename T>
class Handler {
void Receive() {
static_cast<T*>(this)->Receive();
}
void Send() {
static_cast<T*>(this)->Send();
}
};
class B1: public Handler<B1>
{
void Receive() {
...
}
void Send() {
...
}
};
int main() {
B1 handler1;
handler1.Receive();
...
}
这避免了虚拟方法。它也与您的 非常相似class Handler
,但它的优点是不需要T *object
成员变量。
推荐阅读
- node.js - 如果 node.js 中的验证失败,如何保留表单数据?
- python - Pytest 覆盖:在多个文件夹上运行 cov
- powershell - Get-Process 不适用于 .net 形式的按钮按下
- php - Laravel 中新模型的问题 CORS 策略
- javascript - 使用 mobx-react-lite 和 React hooks 在 React Native 中获取函数
- javascript - 使用移动图库中图片上的共享按钮将其上传到 PWA
- swift - 无法在 APIClient 的当前上下文中推断闭包类型
- javascript - 通过回调从异步函数返回数据是未定义的
- java - 如何从excel中读取数据,只有一列
- c++ - 从 MATLAB 调用 C++ 可执行文件时如何绕过错误对话框?