내가 처음 custom deleter를 봤을 때에는, shared_ptr 생성자에서 한 번 custom deleter를 지정해주면 그 다음부터 reset()을 하더라도 항상 처음에 지정했던 deleter를 불러줄 거라는 기대가 있었다. 그래서 테스트를 해봤더니 그런게 아니네. custom deleter를 유지하고 싶다면 reset()을 할 때 deleter도 같이 넘겨줘야 한다.
아래 테스트 코드는 custom deleter를 지정하지 않고 reset()한 경우에는 custom deleter가 호출되지 않는다는 걸 Google Test를 이용해서 보여주는 코드이다.
- class TestSharedPtrFixture : public testing::Test
{
public:
std::stringstream ss;
TestSharedPtrFixture()
: ss(std::stringstream::out | std::stringstream::out)
{
}
void Deleter(int* p)
{
ss << "dtor()" << std::endl;
delete p;
}
};
// shared_ptr 기능을 제대로 알기 위한 테스트
// shared_ptr reset() 메서드에서 dtor를 별도로 지정하는 경우 reset() 메서드를 실행할 때마다 dtor를 지정해줘야 함
TEST_F(TestSharedPtrFixture, TestReset)
{
ss.str("");
std::tr1::shared_ptr<int> sp;
ASSERT_EQ(NULL, sp.get());
sp.reset(new int(9), std::bind1st(std::mem_fun1(&TestSharedPtrFixture::Deleter), this));
sp.reset(new int(8));
sp.reset();
ASSERT_EQ("dtor()\n", ss.str());
}
// shared_ptr 생성자에서 dtor를 별도로 지정하는 경우 reset() 메서드를 실행할 때마다 dtor를 지정해줘야 함
TEST_F(TestSharedPtrFixture, TestCtor)
{
ss.str("");
std::tr1::shared_ptr<int> sp(new int(9), std::bind1st(std::mem_fun1(&TestSharedPtrFixture::Deleter), this));
ASSERT_EQ(9, *sp.get());
sp.reset(new int(8));
sp.reset();
ASSERT_EQ("dtor()\n", ss.str());
}
이 글은 스프링노트에서 작성되었습니다.