C++ 在从基类构造函数创建的单独线程中调用纯虚拟函数 #包括 #包括 #包括 阶级基础{ 受保护的: pthread\u t receiverThreadID; Base(){ pthread_创建(&receiverThreadID,NULL,threadFunction,this); } ~Base(){ } 虚拟void handleEvent()=0; 静态void*threadFunction(void*arg){ while(true){ //此线程通过recvfrom()接收UDP。消息可以随机传入。我使用sleep()模拟阻塞等待 睡眠(1); ((Base*)arg)->handleEvent(); } 返回0; } }; 派生类:公共基{ 虚拟void handleEvent(){ //做点什么 printf(“hello\n”); } 公众: 派生(){} ~Derived(){} }; int main(){ 派生的; 睡眠(10); }

C++ 在从基类构造函数创建的单独线程中调用纯虚拟函数 #包括 #包括 #包括 阶级基础{ 受保护的: pthread\u t receiverThreadID; Base(){ pthread_创建(&receiverThreadID,NULL,threadFunction,this); } ~Base(){ } 虚拟void handleEvent()=0; 静态void*threadFunction(void*arg){ while(true){ //此线程通过recvfrom()接收UDP。消息可以随机传入。我使用sleep()模拟阻塞等待 睡眠(1); ((Base*)arg)->handleEvent(); } 返回0; } }; 派生类:公共基{ 虚拟void handleEvent(){ //做点什么 printf(“hello\n”); } 公众: 派生(){} ~Derived(){} }; int main(){ 派生的; 睡眠(10); },c++,C++,您不应该从类的构造函数中调用纯虚函数,但是在构造函数中创建一个线程来调用纯虚函数可以吗?是否存在比赛条件的风险?上面的代码没有任何运行时错误 如果像我这样编写代码是不合适的,你应该如何解决它?如果threadFunction()在Derived的构造函数完成之前调用handleEvent(),这可能会崩溃 为什么不将pthread\u create调用放在另一个函数中,比如说,start(),并在构建对象后调用它呢 #include <unistd.h> #include <p

您不应该从类的构造函数中调用纯虚函数,但是在构造函数中创建一个线程来调用纯虚函数可以吗?是否存在比赛条件的风险?上面的代码没有任何运行时错误


如果像我这样编写代码是不合适的,你应该如何解决它?

如果
threadFunction()
Derived
的构造函数完成之前调用
handleEvent()
,这可能会崩溃

为什么不将
pthread\u create
调用放在另一个函数中,比如说,
start()
,并在构建对象后调用它呢

#include <unistd.h>
#include <pthread.h>
#include <stdio.h>

class Base {
protected:
    pthread_t receiverThreadID;
    Base() {
        pthread_create(&receiverThreadID,NULL,threadFunction,this);
    }
    ~Base() {

    }

    virtual void handleEvent() = 0;
    static void* threadFunction(void* arg) {
        while(true) {
            // This threads receives UDP via recvfrom(). The messages can come in randomly. I use sleep() to simulate a blocking wait
            sleep(1);
            ((Base*)arg)->handleEvent();
        }
        return 0;
    }
};

class Derived : public Base {
    virtual void handleEvent() {
        // Do something
        printf("hello\n");
    }

public:
    Derived() {}
    ~Derived() {}

};

int main() {
    Derived derived;

    sleep(10);
}

如果您在线程中调用它或直接调用它并不重要,那么您不应该在派生函数完全构造之前调用纯虚函数,而这发生在基本函数构造之后

您的睡眠使此代码运行,但并不安全

如果您想要一个安全的版本,我有两个选项:

  • 使用互斥锁或类似的机制来防止线程在构造函数完成之前调用函数
  • (这可能是更好的选择):在构造函数之后调用的函数中启动线程。您可能希望在这里使用工厂函数来确保始终调用它

  • 当构造函数没有完全执行时调用虚函数是错误的

    正如其他建议,请确保有另一个使用此虚拟函数的函数。并在创建对象后调用此函数。 例如


    希望这能解决问题

    您需要一些同步机制来保证构造函数完成。这就是这里最重要的,当线程被创建时是不相关的。我可以从派生的构造函数调用start()吗?@mbarnapam:No。特别是,如果您继承
    Derived
    并再次重写
    handleEvent
    ,该怎么办?您可以在派生的构造函数中调用start(),但是请注意,将调用虚拟函数的派生版本(这可能是个问题,也可能不是问题,取决于您是否进一步派生派生)。也就是说,在构造函数中调用虚拟函数是有明确定义的,但您需要知道会发生什么(这可能与您预期的不同)。
    class Base {
    protected:
        pthread_t receiverThreadID;
        Base() {}
        ~Base() {}
    
        void start() {
            pthread_create(&receiverThreadID,NULL,threadFunction,this);
        }
    
        ...
    };
    
    class Base{
        static void *create_thread(void * arg){
             pthread_create(&receiverThreadID,NULL,threadFunction,this);
        }   
    
    };
    // client call something like this.
    Base * b = new Derived();
    b->create_thread();