Ничего не понимаю..
От: Аноним  
Дата: 14.09.05 15:52
Оценка:
Почему не работает этот код???????

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() ?
Re: Ничего не понимаю..
От: Ovl Россия  
Дата: 14.09.05 15:59
Оценка: -1
Здравствуйте, Аноним, Вы писали:

А>Почему не работает этот код???????


маловато информации. например, непонятно, что и как попадает в 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() ?

может и должна. только где она вызывается — не видно
Read or Die!
Как правильно задавать вопросы
Как правильно оформить свой вопрос
Автор: anvaka
Дата: 15.05.06
Re: Ничего не понимаю..
От: Erop Россия  
Дата: 14.09.05 16:03
Оценка: +4
Здравствуйте, Аноним, Вы писали:

А>Почему не работает этот код???????


А>
    pObj->run();                       // Вот на этом падает в run-time с сообщением 'pure virtual function called'


А>Чего-то я совсем запутался — разве не должна вызваться Derived::run() ?


Есть теория, что к моменту вызова pObj->run() объект Derived d уже разрушен.
При этом во время вызова ~Base указатель на таблицу виртуальных функций этого объекта переставляется на таблицу для класса Base.
Отсюда и описанное падение.

С уважением.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Ничего не понимаю..
От: Ellin Россия www.rsdn.ru
Дата: 14.09.05 16:04
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Почему не работает этот код???????


А>
А>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' 
                //???
                //может pBase->run(); ?
А>}

А>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() ?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Ничего не понимаю..
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 14.09.05 16:04
Оценка:
Здравствуйте, Ovl, Вы писали:

Ovl>маловато информации. например, непонятно, что и как попадает в Base::start


Посредством вызова _beginthredex.

Ovl>а может поможет вот это

А>>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() ?


Ovl>может и должна. только где она вызывается — не видно.


_beginthreadex "запускает" start(), та в свою очередь вызывает run.
Re: Ничего не понимаю..
От: Aramis1  
Дата: 14.09.05 16:06
Оценка: -1 :)))
Здравствуйте, Аноним, Вы писали:

А>Почему не работает этот код???????


А>
А>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 получется абстрактным (т.к. в нем есть хотя-бы одна виртуальная ф-ция), поэтому все методы класа нужно переопределить и реализовать в производном класе
Re[2]: Ничего не понимаю..
От: Аноним  
Дата: 14.09.05 16:11
Оценка:
Здравствуйте, Erop, Вы писали:

E>Есть теория, что к моменту вызова pObj->run() объект Derived d уже разрушен.


Воистину так!!!
Да, много неожиданных эффектов проявляется на быстрых машинах. А как с этим побороться?
Re[3]: Ничего не понимаю..
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 14.09.05 16:13
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Erop, Вы писали:


E>>Есть теория, что к моменту вызова pObj->run() объект Derived d уже разрушен.


А>Воистину так!!!

А>Да, много неожиданных эффектов проявляется на быстрых машинах.

Кстати, на моей машине (Athlon XP 2000+ 512 Mb) таких спецэффектов не наблюдалось

А>А как с этим побороться?


Увеличить время жизни pObj до выхода из потока, создаваемого _beginthredex, например.
Re[3]: Ничего не понимаю..
От: Erop Россия  
Дата: 14.09.05 16:17
Оценка: +1
Здравствуйте, Аноним, Вы писали:

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 loop
   while(1)
   {
      // ...
   }
}


А>>А как с этим побороться?

A>Увеличить время жизни pObj до выхода из потока, создаваемого _beginthredex, например.

Логично.
Как-то не подумал про такой спецэффект. Что локальную переменную нельзя в поток передавать — знаю, а вот про то что объект класса должен жить пока работает поток — не сообразил.
Re[2]: Ничего не понимаю..
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 14.09.05 16:28
Оценка:
Здравствуйте, Aramis1, Вы писали:

A>клас Base получется абстрактным (т.к. в нем есть хотя-бы одна виртуальная ф-ция), поэтому все методы класа нужно переопределить и реализовать в производном класе


А>>class Base
А>>{
А>>    virtual void run() = 0;
А>>    static UINT WINAPI start( void *pObj );
А>>    void Start();
А>>};

<...>

А>>class Derived : public Base
А>>{
А>>    void run(){}
А>>};
Re: Ничего не понимаю..
От: MaximE Великобритания  
Дата: 14.09.05 20:17
Оценка: -1
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.

Т.е.
_beginthreadex(..., static_cast<Base*>(this), ...)


Хотя, проблема у тебя здесь скорее не в этом.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[2]: Ничего не понимаю..
От: Ovl Россия  
Дата: 15.09.05 07:58
Оценка:
и за что минус, уважаемый vamp?
Read or Die!
Как правильно задавать вопросы
Как правильно оформить свой вопрос
Автор: anvaka
Дата: 15.05.06
Re[3]: Ничего не понимаю..
От: Ovl Россия  
Дата: 15.09.05 08:00
Оценка:
Здравствуйте, Ovl, Вы писали:

Ovl>и за что минус, уважаемый vamp?


дошло это просто несогласие
Read or Die!
Как правильно задавать вопросы
Как правильно оформить свой вопрос
Автор: anvaka
Дата: 15.05.06
Re[2]: Ничего не понимаю..
От: ansi  
Дата: 15.09.05 10:10
Оценка:
Здравствуйте, MaximE, Вы писали:


ME>Этот код не должен работать (но иногда может).


ME>Тебе нужно явно кастить this в Base*, т.к. подобъект Base может не располагаться по тому же адресу, что и this объекта, который ты передаешь в _beginthreadex.


ME>Т.е.

ME>
ME>_beginthreadex(..., static_cast<Base*>(this), ...)
ME>


ME>Хотя, проблема у тебя здесь скорее не в этом.


Зачем? В метод передается уже указатель именно на Base (т.к. этор метод класса Base);
new RSDN@Home(1.1.4, 303) << new Message(); std::head::ear << "тссссссссс";
Re[3]: Ничего не понимаю..
От: MaximE Великобритания  
Дата: 15.09.05 12:31
Оценка: +1 :))) :))
Здравствуйте, ansi, Вы писали:

ME>>Тебе нужно явно кастить this в Base*, т.к. подобъект Base может не располагаться по тому же адресу, что и this объекта, который ты передаешь в _beginthreadex.


A>Зачем? В метод передается уже указатель именно на Base (т.к. этор метод класса Base);


Есть ощущение, что я херню написал
Re: Ничего не понимаю..
От: dad  
Дата: 16.09.05 04:57
Оценка:
А>// где-то в main():
А> Derived d;
А> d.Start();

А>[/ccode]


А>Чего-то я совсем запутался — разве не должна вызваться Derived::run() ? :???:


так ты указатель на стековый объект передаешь.
Веру-ю-у! В авиацию, в научную революци-ю-у, в механизацию сельского хозяйства, в космос и невесомость! Веру-ю-у! Ибо это объективно-о! (Шукшин)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.