РЕДАКТИРОВАТЬ:С ++: Привязка к базовому классу
В следующем коде container::push
принимает объект типа T
, производный от base
в качестве аргумента, и сохраняет в векторе указатель на метод bool T::test()
.
container::call
вызывает каждый из сохраненных методов в контексте к объекту члена p
, который имеет тип base
, не T
. Он работает до тех пор, пока вызываемый метод не ссылается ни на какой член вне base
, и если test()
не объявлен virtual
.
Я знаю, что это уродливо и может быть даже не совсем правильным.
Как я могу сделать то же самое лучше?
#include <iostream>
#include <tr1/functional>
#include <vector>
class base {
public:
base(int v) : x(v)
{}
bool test() const { // this is NOT called
return false;
}
protected:
int x;
};
class derived : public base {
public:
bool test() const { // this is called instead
return (x == 42);
}
};
class container {
public:
container() : p(42)
{}
template<typename T>
void push(const T&) {
vec.push_back((bool (base::*)() const) &T::test);
}
void call() {
std::vector<bool (base::*)() const>::iterator i;
for(i = vec.begin(); i != vec.end(); ++i) {
if((p .* (*i))()) {
std::cout << "ok\n";
}
}
}
private:
std::vector<bool (base::*)() const> vec;
base p;
};
int main(int argc, char* argv[]) {
container c;
c.push(derived());
c.call();
return 0;
}
В чем вопрос? – outis
Изменение вопроса после его ответа приводит к целому ряду замешательств (внезапно есть ответы, которые не связаны или игнорируют часть вопроса только потому, что вопрос изменился). Пожалуйста, не надо. Добавьте другой вопрос, если вам это нужно. И, кстати, обычно это помогает, если вы добавляете то, что хотите, и почему оно вам нужно, а не код, который у вас есть. –
Вы правы, я голосовал, чтобы закрыть вопрос. –