我想用一个方法“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/