Sıralı bir dizi işlev nesnesini sırayla yürütecek bir mekanizma tasarlıyorum. Bu işlev nesneleri çalışma zamanı sırasında atanır ve sorun şu şekildedir: Bu işlev nesnesinin parametre türü farklıdır. Yapmak istediğim neSırayla farklı parametre türlerinin tekil işlevli nesneleri nasıl yürütülür?
böyle bir şeydir:
class command_sequence {
private:
/* some kind of container */
public:
void add(FUNC_OBJ &func, PARAM val);
void run(void);
};
class check_temperature {
public:
void operator() (int celsius) {
if(celsius > 26) {
cooler.switch_on();
}
}
};
class log_usage {
public:
void operator() (std::string username) {
username.append(" logged in");
syslog(LOG_NOTICE,username.c_str());
}
};
command_sequence sequence;
log_usage logger;
check_temperature checker;
sequence.add(logger, std::string("administrator"));
sequence.add(checker, lobbyMeter.read_temperature());
sequence.add(logger, std::string("lecture"));
sequence.add(checker, classroomMeter.read_temperature());
sequence.run();
C kodu yazıyorum, ben parametre olarak * hükümsüz sürer hiçbir seçim ama geri çağırma işlevi işaretçisi var. Ama şimdi C++ ile çalışıyorum, bununla başa çıkmak için şık bir yol olmalı. Şimdi düşünebiliriz
iyi yolu neredeyse bir soyut sarıcı sınıftan kalıtımla bir şablon sınıfını ilan edilir: Bu yaklaşım ihtiyaçlarımı sığabilecek
class command_sequence {
private:
class runner {
public:
virtual void execute(void) = 0;
};
template <class FUNC, typename T> class func_pair : public runner {
private:
FUNC &func;
T param;
public:
func_pair(FUNC &f, const T &t) : func(f),param(t) { }
void execute(void) {
func(param);
}
};
std::vector<runner*> funcQueue;
public:
template <class FUNC, typename T> void add(FUNC &obj, const T &t) {
funcQueue.push_back(new func_pair<FUNC,T>(obj,t));
}
void run(void) {
std::vector<runner*>::iterator itr=funcQueue.begin();
for(;itr!=funcQueue.end();++itr) {
(*itr)->execute();
delete (*itr);
}
}
};
, ancak tahsis ve her giriş için template_pair serbest olacaktır. Bu işlemin bellek parçasına neden olup olacağına dair hiçbir fikrim yok, çünkü bu işlem süreçte oldukça sıkça çağrılacak.
Bunu yapmanın daha iyi bir yolu var mı?
Gerçekten etkileyici. Boost :: bind() işlev nesnelerini kabul edebileceğini hiçbir fikrim yok; ama mantıklı. Bu aradığım cevap gibi görünüyordu. Teşekkürler. – RichardLiu