Здравствуйте, ansi, Вы писали:
ME>>Тебе нужно явно кастить this в Base*, т.к. подобъект Base может не располагаться по тому же адресу, что и this объекта, который ты передаешь в _beginthreadex.
A>Зачем? В метод передается уже указатель именно на Base (т.к. этор метод класса Base);
Здравствуйте, Аноним, Вы писали:
А>Почему не работает этот код???????
А>
pObj->run(); // Вот на этом падает в run-time с сообщением 'pure virtual function called'
А>Чего-то я совсем запутался — разве не должна вызваться Derived::run() ?
Есть теория, что к моменту вызова pObj->run() объект Derived d уже разрушен.
При этом во время вызова ~Base указатель на таблицу виртуальных функций этого объекта переставляется на таблицу для класса Base.
Отсюда и описанное падение.
С уважением.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Аноним, Вы писали:
А>Почему не работает этот код???????
А>
А>class Base
А>{
А> virtual void run() = 0;
А> static UINT WINAPI start( void *pObj );
А> void Start();
А>};
А>void Base::start(void * pObj)
А>{
А> Base * pBase = (Base*)pObj;
pObj->>run(); // Вот на этом падает в run-time с сообщением 'pure virtual function called'
А>}
А>void Base::Start()
А>{
А> unsigned tid;
А> _beginthreadex(
А> NULL, // security attributes
А> 0, // use default stack size
А> start, // thread function
А> this, // argument list
А> 0, // start running
А> &tid // out: thread id
А> );
А>}
А>class Derived : public Base
А>{
А> void run(){}
А>};
А>// где-то в main():
А> Derived d;
А> d.Start();
А>
А>Чего-то я совсем запутался — разве не должна вызваться Derived::run() ?
клас Base получется абстрактным (т.к. в нем есть хотя-бы одна виртуальная ф-ция), поэтому все методы класа нужно переопределить и реализовать в производном класе
Здравствуйте, Аноним, Вы писали:
А>Почему не работает этот код???????
маловато информации. например, непонятно, что и как попадает в Base::start
А>void Base::start(void * pObj) А>{ А> Base * pBase = (Base*)pObj; pObj->>run(); // Вот на этом падает в run-time с сообщением 'pure virtual function called' А>}
а может поможет вот это А>void Base::Start() А>{ А> unsigned tid;
А> _beginthreadex( А> NULL, // security attributes А> 0, // use default stack size А> start, // thread function А> (Base*) this, // argument list А> 0, // start running А> &tid // out: thread id А> ); А>}
А>Чего-то я совсем запутался — разве не должна вызваться Derived::run() ?
может и должна. только где она вызывается — не видно
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Erop, Вы писали:
E>>Есть теория, что к моменту вызова pObj->run() объект Derived d уже разрушен.
А>Воистину так!!! А>Да, много неожиданных эффектов проявляется на быстрых машинах.
Кстати, на моей машине (Athlon XP 2000+ 512 Mb) таких спецэффектов не наблюдалось
А>А как с этим побороться?
Увеличить время жизни pObj до выхода из потока, создаваемого _beginthredex, например.
Здравствуйте, Аноним, Вы писали:
E>>Есть теория, что к моменту вызова pObj->run() объект Derived d уже разрушен. А>Воистину так!!! А>Да, много неожиданных эффектов проявляется на быстрых машинах. А как с этим побороться?
Ну общий рецепт -- продумать как должны жить в твоей программе объекты и как они должны взаимодействовать с потоками
Может быть поручить разрушать объект Derived тому потоку, который выполняет Derived::run? Ну или ещё как.
Выделять его по new, скажем, или вообще сделать статическим
Но лучше всего выяснить на кой там вообще нужна многопоточность. Без неё часто лучше
Во всяком случае отлаживать проще и даже просто воспроизводить поведение
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Ничего не понимаю..
От:
Аноним
Дата:
14.09.05 16:19
Оценка:
Здравствуйте, Alxndr, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
А>>Здравствуйте, Erop, Вы писали:
E>>>Есть теория, что к моменту вызова pObj->run() объект Derived d уже разрушен.
А>>Воистину так!!! А>>Да, много неожиданных эффектов проявляется на быстрых машинах.
A>Кстати, на моей машине (Athlon XP 2000+ 512 Mb) таких спецэффектов не наблюдалось
А у меня код такой:
main()
{
{
// Test
Derived d;
d.Start();
}
// main loopwhile(1)
{
// ...
}
}
А>>А как с этим побороться? A>Увеличить время жизни pObj до выхода из потока, создаваемого _beginthredex, например.
Логично.
Как-то не подумал про такой спецэффект. Что локальную переменную нельзя в поток передавать — знаю, а вот про то что объект класса должен жить пока работает поток — не сообразил.
On Wed, 14 Sep 2005 19:52:30 +0400, wrote:
> Почему не работает этот код??????? > >
> class Base
> {
> virtual void run() = 0;
> static UINT WINAPI start( void *pObj );
> void Start();
> };
>
> void Base::start(void * pObj)
> {
> Base * pBase = (Base*)pObj;
> pObj->run(); // Вот на этом падает в run-time с сообщением 'pure virtual function called'
> }
>
> void Base::Start()
> {
> unsigned tid;
>
> _beginthreadex(
> NULL, // security attributes
> 0, // use default stack size
> start, // thread function
> this, // argument list
> 0, // start running
> &tid // out: thread id
> );
> }
>
> class Derived : public Base
> {
> void run(){}
> };
>
> // где-то в main():
> Derived d;
> d.Start();
>
>
> > Чего-то я совсем запутался — разве не должна вызваться Derived::run() ?
Этот код не должен работать (но иногда может).
Тебе нужно явно кастить this в Base*, т.к. подобъект Base может не располагаться по тому же адресу, что и this объекта, который ты передаешь в _beginthreadex.
Здравствуйте, Aramis1, Вы писали:
A>клас Base получется абстрактным (т.к. в нем есть хотя-бы одна виртуальная ф-ция), поэтому все методы класа нужно переопределить и реализовать в производном класе
ME>Этот код не должен работать (но иногда может).
ME>Тебе нужно явно кастить this в Base*, т.к. подобъект Base может не располагаться по тому же адресу, что и this объекта, который ты передаешь в _beginthreadex.
ME>Т.е. ME>