我想用在线程中运行任务“ work()”的方法“ execute()”创建基类“ process”。例如,当我创建派生类“产品”以及带有对象“ 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
答案 0 :(得分:7)
您的代码具有不确定的行为,因为您加入的位置不正确。
尽管您的类在销毁时正确地加入了线程,但请确保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();
}
更好的类设计应允许您以不太容易出错的方式进行操作。