【发布时间】:2019-07-18 08:27:22
【问题描述】:
我目前正在重构代码以使原始指针使用智能指针,并对此类进行测试,但遇到了智能指针被过早删除的问题
这是一个例子:
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 成为调用基类析构函数时还活着吗?
注意:我需要在 helper 的 createObject 中调用一些 API,这就是我嘲笑它的原因。我不能将帮助程序作为依赖项注入,这就是为什么我必须用sut_->helper.reset(helperMock_.get());“破解”它的原因@
【问题讨论】:
标签: c++ pointers googletest gmock