Рассматривали ли вы упаковку ExecutorService? Создайте
CleanShutdownExecutorService implements Executor
, который делегирует все вызовы другому исполнителю, но сохраняет фьючерсы в своем собственном списке. CleanShutdownExecutorService может затем иметь метод cancelRemainingTasks (), который вызывает shutdown (), а затем вызывает cancel (false) для всех фьючерсов в своем списке.
This following article extensively discusses member function pointers in C++, how they are implemented and where are the flaws. It also handles virtual member function pointers and much more. I think it will answer all your questions.
http://www.codeproject.com/KB/cpp/FastDelegate.aspx
It also shows how to implement delegates in C++ and what pitfalls you might trap in.
With Kind Regards,
Ovanes
Конечно, это так. Ваш код ничем не отличается от простого вызова чистого виртуального метода следующим образом:
void Test()
{
Base* ptr = new Derived;
ptr->sayHi();
delete ptr;
}
Единственное отличие состоит в том, что у вас есть другой механизм для выполнения вызова, и в данном случае через callVirtual ().
Как сказал Магнус Ског, часть шаблона на самом деле не актуальна. Все сводится к следующему:
(ptr->* &Base::sayHi)()
похоже работает, но
ptr->Base::sayHi()
явно не работает, потому что sayHi является чисто виртуальным.
Мне не удалось найти ничего в стандарте о том, что происходит, когда вы берете адрес виртуальной или чистой виртуальной функции. Я не уверен, что это законно. Тем не менее, он работает в GCC и MSVC, и онлайн-компилятор Comeau тоже не жалуется.
Править
Даже если он действителен, как говорят ваши правки, мне все еще интересно, что это значит.
Если мы для простоты предположим, что sayHi
не является чистым (поэтому существует определение Base :: sayHi
), тогда что произойдет, если я возьму его адрес? Получу ли я адрес Base :: sayHi,
Вызов ptr-> Base :: sayHi ()
вызывает sayHi
в базовом классе, но взяв адрес Base :: sayHi
, я получаю адрес Получено :: sayHi
Мне это кажется непоследовательным. Есть ли какое-то объяснение того, что мне не хватает?
Я предполагаю, что это неопределенный. Я ничего не нашел в спецификации.
виртуальные методы реализованы с использованием концепции, называемой vtable .
Я бы сказал, что это зависит от реализации компилятора. Я не думаю, что это имеет значение, что это чисто виртуальный, то же самое произошло бы, если бы он был просто виртуальным.
Я только что скомпилировал ваш код с помощью Visual Studio 2008 и скомпилировал exe.j _ ?? _ 9Base @ @ $ B3AE
; void __thiscall Base___vcall_(Base *)
j_??_9Base@@$B3AE proc near
jmp ??_9Base@@$B3AE ; [thunk]: Base::`vcall'{4,{flat}}
j_??_9Base@@$B3AE endp
Все, что делает thunk-функция, это использует vtable для перехода к методу реального класса.