C++;:在基类中使用具有泛型虚拟函数的异步回调 目前我正在编写一个C++程序,它应该包含某种非常通用的基类。它将具有一些受保护的功能 class Base{ virtual void doA() = 0; virtual void doB() = 0; \\[see below]... }
它们将异步执行,并在完成后作为回调调用:C++;:在基类中使用具有泛型虚拟函数的异步回调 目前我正在编写一个C++程序,它应该包含某种非常通用的基类。它将具有一些受保护的功能 class Base{ virtual void doA() = 0; virtual void doB() = 0; \\[see below]... },c++,generics,inheritance,C++,Generics,Inheritance,它们将异步执行,并在完成后作为回调调用: virtual void doACallback(type1 param1, type2 param2) = 0; virtual void doBCallback() = 0; 我的问题是doA和doB的实现对于每个子类都是不同的,回调方法应该能够接收不同的参数(类型和数量)。在基类中保留回调方法声明时,是否可以管理此操作?也许这可以通过另一种方式实现。我对C++仍然是新的。 注意:Base不仅包含纯虚函数 编辑:因为有人问。我想定义子类的一般“
virtual void doACallback(type1 param1, type2 param2) = 0;
virtual void doBCallback() = 0;
我的问题是doA
和doB
的实现对于每个子类都是不同的,回调方法应该能够接收不同的参数(类型和数量)。在基类中保留回调方法声明时,是否可以管理此操作?也许这可以通过另一种方式实现。我对C++仍然是新的。
注意:Base不仅包含纯虚函数
编辑:因为有人问。我想定义子类的一般“外观”。我的具体场景非常复杂,但让我们尝试一个示例:
class Base{
virtual void sendData() = 0;
virtual void sendDataCallback() = 0;
}
class SubclassA:public Base{
void sendData() override{
//send Data by using LibraryA
}
void sendDataCallback(ErrorCode aErrorCode) override{
//handle error Code
}
}
class SubclassB:public Base{
void sendData() override{
//send Data by using LibraryB
}
void sendDataCallback(ErrorCode aErrorCode, Response aResponse) override{
//handle error Code and handle response
}
}
这不是确切的情况,但也许这澄清了这个想法
编辑2:如果有人想知道:最后我选择在子类中定义回调。不,这是不可能的。我也不明白这有什么意义。实现回调的子类必须派生自包含do函数实际实现的类,因此我不理解为什么具有do实现的类不能声明回调函数。几乎任何事情都是可能的。您可以强制转换到
void*
并返回到派生类中:
struct ScrewThis
{
void addCallback(void * cb) { callbacks.push_back(cb); }
void executeCallback(int index) const = 0;
std::vector<void*> callbacks;
};
struct TotalHell : ScrewThis
{
void executeCallback(int index) const
{
auto callback
= static_cast<std::function<int(int,int)> const*>(callbacks[index]);
auto i = callback(4,2);
//...
}
};
struct
{
void addCallback(void*cb){callbacks.push_back(cb);}
void executeCallback(int index)const=0;
std::向量回调;
};
结构TotalHell:去他妈的
{
void executeCallback(int索引)常量
{
自动回拨
=静态_cast(回调[索引]);
自动i=回调(4,2);
//...
}
};
但你为什么要这么做?这是一场维护噩梦。其他开发人员将看起来像一个it工程师,并立即想自杀…或你…或更可能两者兼而有之
您这样做只是为了共享“公共”代码(“公共”在短引号中,因为您可以看到它不是公共代码)。在OOP早期犯的一个巨大错误是认为继承,这就是增加重用。这是错误的。您可以通过组合来增加重用
当你不得不重新实现多态性来做你想做的事情时,是时候想想你想做的事情可能不是你应该做的事情了。你考虑过使用
命令模式作为回调吗?
您的派生类(从基派生)应该使用CommandA和CommandB类来执行所需的行为
class Command
{
public:
virtual void execute() = 0;
};
class CommandA : public Command
{
public:
CommandA();
void execute() override;
};
class CommandB : public Command
{
public:
CommandB(int param1, double param2);
void execute() override;
};
对于混凝土等级:
class Concrete : public Base
{
public:
Concrete(Command* callA, Command* callB): callbackA(callA), callbackB(callB)
{}
void doA()override
{
...
callbackA->execute();
}
void doB()override
{
...
callbackB->execute();
}
private:
Command* callbackA;
Command* callbackB;
};
选中“非循环访问者模式”。向下投射是必需的,因此您可能会得到一个运行时异常,包括您想要的接口。你能举个例子吗?我加了个例子。请参阅我的原始问题。如何调用sendDataCallback
?据我所知,它可能是sendData
中的最后一个调用,因此不需要在类Base
中。看看我原来的问题。@little_planet-No。你想做的事情根本没有意义。当这种关系不存在时,你似乎在试图表达一种“是-是”的关系。就像试图从树上继承汽车一样。