我试图实现类似命令模式的东西来控制具有相同界面的多个组件。每个组件都必须实现以下接口。
class ComponentInterface {
public:
virtual int start() = 0;
virtual int stop() = 0;
};
每个派生组件都会实现一些特定的方法。
class Led : public ComponentInterface {
public:
/**
* Implements Interface methods
*/
int start() { return 0; }
int stop() { return 0; }
private:
int setIntensity(int attrs[], int returns[]) {
printf( "Set intensity called" );
return 1;
}
};
主要思想是每个子类将可调用成员函数存储在指针数组中,并且在ComponentInterface
类中将实现一个可以根据命令的索引调用此函数的方法。
class ComponentInterface {
public:
...
// for storing the pointers
int (ComponentInterface::*commandsArray[10])(int[], int[]);
// to call the member functions
int command(int commandId, int attrsList[], int responseList[]) {
return (this->*commandsArray[commandId])(attrsList, responseList);
}
}
class Led : public ComponentInterface {
public:
Led(float* ledIntensity) {
// store the command in the array
this->commandsArray[0] = (&Led::setIntensity);
}
// redefine the array for pointers of this subclass
int (Led::*commandsArray[5])(int[], int[]);
};
我不熟悉C ++而且我不明白为什么它不起作用,我在调用存储的函数时遇到问题。
使用devC ++进行测试时,我遇到了分段错误。当我尝试在Visual Studio 2013(Visual C ++)中使用调试器进行测试时,它似乎在此行中
(this->*commandsArray[commandId])(attrsList, responseList);
,this
对象指向ComponentInterface对象而不是Led对象。
答案 0 :(得分:2)
您的代码中有两件事是错误的:
你不能“覆盖基类变量”,这一行在派生类中没有意义
// redefine the array for pointers of this subclass
int (Led::*commandsArray[5])(int[], int[]);
此演员表错了
this->commandsArray[0] = (&Led::setIntensity);
它应该是
this->commandsArray[0] = static_cast<int (ComponentInterface::*)(int*,int*)>(&Led::setIntensity);
无论如何,实现您想要的更简洁,更安全的方法如下:
(免责声明:严重剥离,忽略讨论中不重要的一切)
class ComponentInterface {
..
std::vector<std::function<int (int[], int[])>> commandsArray;
}
然后,您可以使用不同的签名存储成员函数(绑定到正确的对象),并只使用组件中的ComponentInterface容器。