class A{ public: virtual ~A(); virtual func()=0; };
class B : public A{ public: virtual ~B(); virtual func(); };
みたいなクラスがあって、生成・破棄を行っているスレッドとは別にバックグラウンドで Bのメソッドfuncを定期的に呼んでる。 バックグラウンドのスレッドがfuncを呼び出す時に pure virtual function calledとかいうエラーが出て終了することがある。 で、Aのfuncを普通の仮想関数に変えたら出なくなった。
で、不思議に思ったんだけど、仮想関数の関数のアドレスってデストラクタで書き換わってるの?
class Bのデストラクタ ↓ funcのアドレスをclass Aのfuncのアドレスに書き換える ↓ class Aのデストラクタ
void func(int n, int mode) { std::srand(static_cast<unsigned>(std::time(NULL))); if (mode == deque) { std::deque<int> d(n); for (int i = 0; i < n; i++) volatile int v = d[std::rand() * n / RAND_MAX]; } else { std::list<int> l(n); for (int i = 0; i < n; i++) { std::list<int>::iterator p(l.begin()); std::advance(p, std::rand() * n / RAND_MAX); volatile int v = *p; } } }
deque 100 elements result = 166 list 100 elements result = 111 deque 1000 elements result = 463 list 1000 elements result = 5192 deque 10000 elements result = 3367 list 10000 elements result = 488152 deque 20000 elements result = 6304 list 20000 elements result = 2041460
vector 100 elements result = 48 deque 100 elements result = 179 list 100 elements result = 109 vector 1000 elements result = 139 deque 1000 elements result = 447 list 1000 elements result = 5234 vector 10000 elements result = 1452 deque 10000 elements result = 3106 list 10000 elements result = 294502 vector 20000 elements result = 2903 deque 20000 elements result = 5991 list 20000 elements result = 1967664