[英]Avoiding multiple near identical declarations for classes that implement a interface
I have a abstract base class called Command
that acts as an interface for commands that can be put in a queue: 我有一个名为
Command
的抽象基类,它充当可以放入队列的命令的接口:
class Command
{
public:
Command(Dependency1& d1, Dependency2& d2);
//...Irrelevant code removed for simplicity...
private:
//Implementations do their work in their override of operator()
virtual void operator()() = 0;
};
Then I have the declarations for the implementations in a header file: 然后我在头文件中有实现的声明:
class FooCommand : public Command
{
public:
using Command::Command;
private:
void operator()() override;
};
class BarCommand : public Command
{
public:
using Command::Command;
private:
void operator()() override;
};
class BazCommand : public Command
{
public:
using Command::Command;
private:
void operator()() override;
};
//...And many more...
So now I have a long list of near identical class declarations, only the name differs a bit. 所以现在我有一长串几乎相同的类声明,只是名称有所不同。 What would be the preferred ways to clean this up besides C style macro's?
除了C风格的宏之外,最好的方法是什么呢?
It all depends on what you need to do in your operator()
. 这完全取决于您在
operator()
需要做什么。
If you don't need any access to the Command
's state, then you could opt to pass a callable to the constructor. 如果您不需要任何访问
Command
的状态,那么您可以选择将callable传递给构造函数。 Like here: 像这儿:
class CallCommand : public Command {
std::function<void()> f;
public:
CallCommand(Dependency1& d1, Dependency2& d2, std::function<void()> f) : Command(d1,d2), f(f) {
}
private:
void operator()() override { f(); }
};
You could then call it by providing either a free function, a lambda, or any std::function
object. 然后,您可以通过提供自由函数,lambda或任何
std::function
对象来调用它。 For example: 例如:
CallCommand c(d1,d2, [](){ cout<<"Hello world"<<endl;});
But if you need to access the class context, then I'm affraid there's no way around a real overriding like you did (and macro is an awful work around for the boilerplate code). 但是如果你需要访问类上下文,那么我很担心没有办法像你那样绕过真正的重写(而宏是一个非常糟糕的解决样板代码的工作)。
The answer is similar to what has been answered by Cristophe but does not use inheritance. 答案与Cristophe所回答的类似,但不使用继承。
You probably don't need inheritance. 您可能不需要继承。 Instead, you could use
std::function
or lambda
expressions. 相反,您可以使用
std::function
或lambda
表达式。 See, for example: 例如,见:
class Command
{
private:
std::function<void()> f;
public:
Command(Dependency1& d1, Dependency2& d2, std::function<void()> f): d1(d1), d2(d2), f(f) {}
void operator()() {
f();
}
};
You could then create objects of Command
and use them wherever in a queue
or vector
as desired. 然后,您可以创建
Command
对象,并根据需要在queue
或vector
任何位置使用它们。
Command call1(0, 0, []() {
std::cout << "call1" << std::endl;
});
Command call2(0, 0, []() {
std::cout << "call2" << std::endl;
});
std::vector<Command> v;
v.emplace_back(call1);
v.emplace_back(call2);
for (size_t i = 0; i < v.size(); i++) {
v[i]();
}
Pre c++11
, you can avoid inheritance by creating function pointers to each function and pass those pointers to the Command
constructor. 在前面的
c++11
,您可以通过创建每个函数的函数指针来避免继承,并将这些指针传递给Command
构造函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.