gpt4 book ai didi

c++ - googletest:测试其基类具有纯虚方法的派生类时的核心转储

转载 作者:行者123 更新时间:2023-11-28 01:13:55 26 4
gpt4 key购买 nike

我有一个抽象基类,它具有处理线程生命周期(启动、停止、加入)的逻辑。线程中执行的工作依赖于实例化的派生类,派生类有几个。

基类如下所示:

class Base {
public:
Base(int i, bool b) : i{i}, b{b}
{
start();
}

virtual bool getB() { return b; };
void stop() { stopWorking = true; workerTh.join(); };

protected:
virtual void start()
{
std::cout << "Base start method" << std::endl;
workerTh = std::thread{ std::bind(&Derived::work, this) };
};
virtual void work() = 0;

std::thread workerTh;
int i;
bool b;

bool stopWorking = false;
};

派生类如下所示:

class Derived : public Base {
public:
Derived(int i, bool b) : Base(i,b) {};

protected:
void work()
{
std::cout << "Derived Work started!" << std::endl;
while (not stopWorking)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
std::cout << "Derived Work ended!" << std::endl;
}
};

它在常规程序中按预期运行,例如:

int main()
{
std::cout << "Starting" << std::endl;
Derived d { 10, false};
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::cout << "Finishing" << std::endl;
d.stop();
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}

但如果我在谷歌测试中执行它,那么我会得到一个核心转储,原因是我在这一行中调用了一个纯虚拟方法:

workerTh = std::thread{ std::bind(&Base::work, this) };

那么,为什么该行在正常程序中按预期工作,但在谷歌测试中崩溃了?我在启动 GTest 时错过了什么吗?

这是测试:

#include "BaseDerived.cc"
#include "gtest/gtest.h"

TEST(BaseDerivedWithThreadTest, FailsCoredumpCallingPureVirtual) {
Derived d { 10, false };
ASSERT_FALSE (d.getB());
}

int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from BaseDerivedWithThreadTest
[ RUN ] BaseDerivedWithThreadTest.FailsCoredumpCallingPureVirtual
Base start method
terminate called without an active exception
pure virtual method called
terminate called recursively
Aborted (core dumped)

我可以通过将线程生命周期代码放到派生类中来解决这个问题,但我发现它非常难看,只是为了让 googletest 开心。

有什么想法吗?

谢谢!

最佳答案

不幸的是,您的代码已损坏:在基类构造函数中,您调用了虚拟的 start()。这将永远不会调用派生类的start() 方法,因为在构造函数中调用时的动态类型不是派生类。这同样适用于虚拟 work() 函数。更糟糕的是,根据调度线程的时间,它可能调用也可能不调用派生类的函数,因为到那时它的类型可能已经更改为派生类的类型。

测试失败也许只是转移注意力,您的代码已损坏。先解决这个问题,然后看看测试是否仍然失败。

关于c++ - googletest:测试其基类具有纯虚方法的派生类时的核心转储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59362246/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com