gpt4 book ai didi

c++ - 由于 GTest 拆卸,智能指针被过早删除

转载 作者:行者123 更新时间:2023-11-28 04:13:48 27 4
gpt4 key购买 nike

我目前正在重构代码,让原始指针使用智能指针,同时也在测试这个类,但遇到智能指针被过早删除的问题

这是一个例子:

class SomeObjectType
{
public:
void init()
{
}
};

class Helper
{
public:
Helper()
{
std::cout << "Helper constructor" << std::endl;
//some codes
}
~Helper()
{
std::cout << "Helper destructor" << std::endl;
//some codes
}
SomeObjectType* createObject()
{
return new SomeObjectType;
//some codes
}
void destroyObject(SomeObjectType* obj)
{
//some codes
}
};

class Base
{
public:
Base()
{
helper = std::make_shared<Helper>();
}
~Base()
{
destroyObject(obj);
}
void Init()
{
obj = createObject();
}
SomeObjectType* createObject()
{
return helper->createObject();
}
void destroyObject(SomeObjectType* obj)
{
helper->destroyObject(obj); // <-- I get the error here
}

protected:
std::shared_ptr<Helper> helper;

private:
SomeObjectType* obj;

FRIEND_TEST(BaseTest , Init_handleSuccess);
};

在我的测试中:

class BaseTest : public ::testing::Test
{
public:
void SetUp()
{
sut_ = std::make_unique<Base>();
helperMock_ = std::make_shared<HelperMock>();
//helperMock_ = new HelperMock; //it works when I dont use smart pointers but of course there is a leak here
}

protected:
std::unique_ptr<Base> sut_;
std::shared_ptr<HelperMock> helperMock_;
//HelperMock* helperMock_; //it works when I dont use smart pointers but of course there is a leak here
};

TEST_F(BaseTest, Init_handleSuccess)
{
auto obj = new SomeObjectType();
sut_->helper.reset(helperMock_.get());
EXPECT_EQ(S_OK, sut_->Init());
}

当我检查日志时,我发现这是(按此顺序)发生的事情:

  • 调用测试设置

  • 调用了基础构造函数

  • 调用了辅助构造函数

  • 测试拆解

  • 已调用辅助析构函数

  • 基类析构函数调用

  • 基本析构函数尝试访问已被删除的 helper = 崩溃!

所以基本上 helper 指针在调用 destroyObject() 之前已经被删除,因为它的生命与我的测试有关。因此,当我将测试更改为对 helper 使用原始指针时,我没有得到双重删除,但随后它变成了泄漏,因为我根本没有删除 helper :)我该怎么做才能在调用基类析构函数时 helper 仍然存在?

注意:我需要在助手的 createObject 中调用一些 API,这就是我要模拟它的原因。我无法将 helper 作为依赖项注入(inject),这就是为什么我必须使用 sut_->helper.reset(helperMock_.get());

来“破解”它

最佳答案

我相信这可能是您的问题...

sut_->helper.reset(helperMock_);

我什至不确定上面的代码是如何编译的,因为我认为 reset 期望 shared_ptr 的原始指针获得所有权。 (正如您在评论中更新的那样:您实际上是在使用 .get() 调用重置)。

使用 shared_ptr 可能犯的最大错误是调用 .get() 或使用 * 运算符 - 并传递返回的原始指针以初始化另一个 shared_ptr。现在你在同一个对象上有两个不同的引用计数 session 。哪一组 shared_ptr 实例首先消失将删除该对象。让另一组 shared_ptr 引用一个已删除的对象。

将上面的替换成这个:

sut_->helper = helperMock_;

我假设 HelperMock 派生自 Helper。

关于c++ - 由于 GTest 拆卸,智能指针被过早删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57090185/

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