在从基类构造函数

时间:2016-02-17 17:26:06

标签: c++

#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);
}

你不应该从类的构造函数中调用纯虚函数,但是可以在构造函数中创建一个线程,然后调用纯虚函数吗?是否有竞争条件的风险?我没有使用上面的代码获得任何运行时错误。

如果不能像我做的那样编码,你应该怎么解决?

3 个答案:

答案 0 :(得分:1)

如果在+-------+------------+------+---------+-----+------+------+ |MonthId|DepartmentId|Salary|Deduction| Paid|Bank_1|Bank_2| +-------+------------+------+---------+-----+------+------+ |01/2016| DEP01 | 1000 | 100 | 900| NULL | NULL | |01/2016| DEP01 | 1000 | 100 | 900| 400 | 500 | |01/2016| DEP02 | 2000 | 50 | 1950| NULL | NULL | |01/2016| DEP02 | 2000 | 50 | 1950| 1400 | 550 | |01/2016| DEP03 | 1500 | 0 | 1500| NULL | NULL | |01/2016| DEP03 | 1500 | 0 | 1500| 0 | 1500 | +---------------------------------------------------------+ 的构造函数完成之前threadFunction()调用handleEvent(),这可能会爆炸。

为什么不将Derived调用放在另一个函数中 - 比如pthread_create - 并在构造对象后调用它?

start()

答案 1 :(得分:1)

如果你在一个线程中调用它或者直接无关紧要,你就不应该在Derived完全构造之前调用纯虚函数 - 这会在构造Base之后发生。

你的睡眠是使这段代码运行的原因,但不安全。

如果你想要一个安全的版本,我会看到两个选项:

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

答案 2 :(得分:0)

当构造函数未完全执行时调用虚函数是错误的。

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

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();

希望这可以解决问题。