我也没想到,有一天我会有这么奇怪的想法,会想让 c++ 的 static 成员具有多态性。需求的产生是这样的:
在点击时具有不同的表现之外
,其他行为都是相同,因此我考虑建立一个基类,用来控制这些相同的属性或行为。没有办法向这个回调方法传参
。根据控件名称做出不同响应
。上面的需求看起来蛮容易的,但操作起来却有不少坑,先看看我产生问题的第一版代码吧。
/*
* base Widget
*/
class Widget
{
private:
//1. 控件名,每个子类名称不同。
std::string mName;
public:
/*
* 回调方法
*
* 2. API 要求,这个 callback 方法只能是静态的;
* 3. 在 callback 里,希望根据不同的组件名,作出不同响应;
* 在 callback 里使用 mName,也就是想在静态方法里使用非静态成员变量
*/
static int callback(int param) {
doWithName(param);
}
/*
* addCallback 是 API 提供的接口,用于给组件添加点击事件回调方法
*
* 4. 这个接口,并没有传递参数的地方,所以 callback 虽然设计了 param,
* 但我并没有办法传过去。
*/
/*
void addCallback(Widget widget, int eventType, int(*callback)(int));
*/
}
/*
* child widget 1
*/
class FirstWidget : public Widget
{
}
/*
* child widget 2
*/
class SecondWidget : public Widget
{
}
在这一版代码里,我希望 mName
能表现出多态性,因此未将其设为静态变量。然后尴尬的发现在静态方法 callback
方法中无法使用,且没法通过参数传递将其传入。那么我就只能把 mName 设成静态的
了,在这一刻,我多么希望静态成员在子类中能有独立地址,从而表现出多态性,然而只能想想。
目前我的解决方法是在每个子类中都有自己的静态变量 mName
,并定义自己的 callback
方法,在基类中新增一个函数指针来指向每个子类的 callback
方法,实现多态性。如下:
/*
* base Widget
*/
class Widget
{
private:
//定义函数指针,指向回调函数
int(*callbackPtr)(int);
public:
Widget(int(*callback)(int)) {
callbackPtr = callback;
}
/* call addCallback */
addCallBack(widget, event, callbackPtr)
/*
void addCallback(Widget widget, int eventType, int(*callback)(int));
*/
}
/*
* child widget 1
*/
class FirstWidget : public Widget
{
private:
//在类中定义 mName
static std::string mName;
//定义 callback 方法
static int mCallback(int param) {
/* do somthing according to mName*/
}
//在子类构造时,将回调方法作为参数传到基类
FirstWidget() : Widget(mCallback) {};
}
/*
* child widget 2
*/
class SecondWidget : public Widget
{
private:
//在类中定义 mName
static std::string mName;
//定义 callback 方法
static int mCallback(int param) {
/* do somthing according to mName*/
}
//在子类构造时,将回调方法作为参数传到基类
SecondWidget() : Widget(mCallback) {};
}
然而,我还是希望:不用在每个子类中都写一次 callback 方法,mName 成员既能在基类的 callback 方法里被使用,又能表现出多态性。求大佬指点一波。