c++ - 为什么子类对象调用母类的成员函数?

标签 c++ multithreading

我想用一个方法“execute()”创建一个基类“process”,它在线程中运行一个任务“work()”。例如,当我创建一个派生类“product”和一个对象“p”时,p.execute() 运行基类的“work()”,即使它是虚拟的。谁能告诉我为什么?

这是我的代码: 1-对于基类:

#include <thread>
#include <iostream>


class process 
{ 

private:

        std::thread  *th;                
public: 
    virtual void work();
    virtual void execute();

    //Delete the copy constructor
    process(const process&) = delete;

    //Delete the Assignment opeartor
    process& operator=(const process&) = delete;

    // Parameterized Constructor
    process();

    // Move Constructor
    process(process && obj);

    //Move Assignment Operator
    process & operator=(process && obj);

    //Destructor
    ~process();

}; 

// Parameterized Constructor
process::process()
{
    th!=NULL;
}

// Move Constructor
process::process(process && obj) : th(std::move(obj.th))
{
    std::cout << "Move Constructor is called" << std::endl;
}

//Move Assignment Operator
process & process::operator=(process && obj)
{
    std::cout << "Move Assignment is called" << std::endl;
    if (th->joinable())
        th->join();
    th = std::move(obj.th);
    return *this;
}


// Destructor
process::~process()
{
    if(th!=NULL){
        if (th->joinable())
          th->join();
    }
}



void process::work() 
{ 
    printf("work of base class \n");
} 


void process::execute() 
{ 
    printf("execute of base class \n");
    th=new  std::thread(&process::work, this);
} 

2-派生类:

class product : public process 
{ 
public: 
    void work();
};


void product::work() {
    printf("work of product class\n");
}

3-主要功能:

int main()
{
    product p;
    p.execute();

    return 0;
}

我希望得到:

execute of base class 
work of product class 

但我实际上得到:

execute of base class 
work of base class 

最佳答案

你的代码有未定义的行为,因为你在错误的地方加入。

尽管您的类在销毁时正确地加入了线程,但要确保 process在线程的持续时间内仍然存在,the derived sub-object is already dead by then .

因此,您可能会看到 product::execute被调用,或 process::execute被调用,或者猫从你的显示器中涌出并开始输入它们自己的程序。

您需要在任何对象被销毁之前加入,无论是从 main 中或者将此代码也添加到 product析构函数。

进行此更改时,我得到了预期的结果。


tl;dr:虚拟调用工作正常,但您的加入位置错误。


此外,您还包括 <iostream>但永远不要使用它,你存储(并移动!)一个指向 std::thread 的指针而不是简单地拥有 std::thread ,并且您的“参数化构造函数”不接受任何参数(并且有一个无用的 th!=NULL ,并且什么都不做)。

以下是针对上述所有问题的快速修复:

#include <thread>
#include <iostream>

class process 
{
private:
    std::thread th;

public:
    virtual void work();
    virtual void execute();
    void endExecution();

    ~process();
}; 

process::~process()
{
    // Just in case, but you don't want to rely on this!
    // See main() -- or do this also in ~product().
    endExecution();
}

void process::work() 
{ 
    std::cerr << "work of base class\n";
} 

void process::execute() 
{
    std::cerr << "execute of base class\n";
    th = std::thread(&process::work, this);
} 

void process::endExecution()
{
    if (th.joinable())
        th.join();
}

class product : public process 
{ 
public: 
    virtual void work() override;
};


void product::work() {
    std::cerr << "work of product class\n";
}

int main()
{
    product p;
    p.execute();
    p.endExecution();
}

( live demo )

更好的类设计应该允许您以不易出错的方式执行此操作。

关于c++ - 为什么子类对象调用母类的成员函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54006799/

相关文章:

java - 我可以在 Java 中的线程中运行线程吗?

c# - 为什么这段代码不会死锁?

C++ 模板化容器扫描器

等待条件下的C++线程死锁

C++ 访问级别

WPF UI 线程状态

c++ - dgeqrf(LAPACK) 在 C++ 中无法正常工作

c++ - 就功能编程而言,C++可以提供什么?

c++ - 为什么没有像 pthread_mutex_t & std::mutex 那样的 std::等价于 pthread_spinlock_t?

java - 使用 ThreadPool 并行化矩阵乘法