我有一些不同类的对象,其中update
,render
和eventHandler
方法对每个类都有相同的原型:
class Menu {
...
public:
Menu ();
void update (WindowState *winState);
void render ();
void eventHandler (SDL_Event *event);
};
class Game {
...
public:
Game (Config *config);
void update (WindowState *winState);
void render ();
void eventHandler (SDL_Event *event);
};
所以,我想“设置活动对象”并通过指针调用这些方法:
struct {
void (*update) (WindowState *winState);
void (*render) ();
void (*eventHandler) (SDL_Event *event);
} routines;
template<class T>
void switchRoutines (T *obj) {
routines.update = &(obj->update);
routines.render = &(obj->render);
routines.eventHandler = &(obj->eventHandler);
}
...
switchRoutines<Game> (&game);
...
routines.render ();
但是,我的类型不匹配:
error: cannot convert 'void (Game::*)(WindowState*)' to 'void (*)(WindowState*)' in assignment
routines.update = &(obj->update);
我已经读过,应该在类中明确声明指向类成员的指针,但我的目标是编写一个通用的,与类无关的例程切换器。
有没有办法没有使用STL或Boost?
答案 0 :(得分:0)
您可以使用类型擦除和模板功能来执行此操作,但必须还要保留对要调用成员函数的实例的引用。
这是一个最小的工作示例:
void *
您的期望已经存在,但是我添加了一个实例switchRoutines<Game> (&game);
routines.render (routines.instance);
指针以使其正常工作:
routines
如果您可以将它添加到public class MainActivity extends AppCompatActivity {
ListView listView;
ArrayList<String> arrayList;
ArrayAdapter<String> arrayAdapter;
String infoText;
int position;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread thread = new Thread(new Runnable(){
@Override
public void run(){
SharedPreferences getPrefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
boolean isFirstStart = getPrefs.getBoolean("started",true);
if(isFirstStart)
{
startActivity(new Intent (MainActivity.this,Intro.class));
SharedPreferences.Editor e = getPrefs.edit();
e.putBoolean("started", false);
e.apply();
}
}
});
thread.start();
listView = (ListView) findViewById(R.id.ListView);
arrayList = new ArrayList<>();
arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, arrayList);
listView.setAdapter(arrayAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent();
intent.setClass(MainActivity.this,EditMessageClass.class);
intent.putExtra(Intent_Constants.INTENT_INFO_DATA,arrayList.get(position).toString());
intent.putExtra(Intent_Constants.INTENT_ITEM_POSITION,position);
startActivityForResult(intent,Intent_Constants.INTENT_REQUEST_CODE_2);
}
});
}
public void onClick(View v){
Intent intent = new Intent();
intent.setClass(MainActivity.this,EditFieldClass.class);
startActivityForResult(intent,Intent_Constants.INTENT_REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if (resultCode==Intent_Constants.INTENT_REQUEST_CODE){
infoText = data.getStringExtra(Intent_Constants.INTENT_INFO_FIELD);
arrayList.add(infoText);
arrayAdapter.notifyDataSetChanged();
}
else if(resultCode==Intent_Constants.INTENT_REQUEST_CODE_2){
infoText = data.getStringExtra(Intent_Constants.INTENT_CHANGED_INFO);
position = data.getIntExtra(Intent_Constants.INTENT_ITEM_POSITION,-1);
arrayList.remove(position);
arrayList.add(position,infoText);
arrayAdapter.notifyDataSetChanged();
}
}
}
对象中,那么这里有一个可行的解决方案。