如何从原始 Ptr 增加共享 Ptr 的计数

How to Increment Count of Shared Ptr from Raw Ptr

我正在进行 class 单元测试并遇到了这个问题 - Device* device/mock 的过早删除:

这是我的 SUT:

Effect::~Effect()
{
    for (auto it = infoList.begin(); it != infoList.end(); ++it)
    {
         (*it)->device->Remove(this, (*it)->position);
         delete *it;
    }
    infoList.clear();
}

HRESULT Effect::Add(Device* device, ULONG position)
{
    Info* info = new Info;
    info->device = device;
    info->position= position;

    auto result = device->Add(position);
    if (result == E_FAIL) return E_FAIL;

    //some other methods being called from 'device'

    infoList.push_back(info);
}

我的测试:

class EffectTest: public ::testing::Test
{
public:
    void SetUp()
    {
        sut_ = std::make_unique<Effect>();
        deviceMock_ = std::make_shared<DeviceMock>();
    }

protected:
    std::unique_ptr<Effect> sut_;
    std::shared_ptr<DeviceMock> deviceMock_;
};


TEST_F(EffectTest, Add)
{
    EXPECT_CALL(*deviceMock_, Add(_).WillRepeatedly(Return(S_OK));
    EXPECT_CALL(*deviceMock_, Remove(_, _)).WillRepeatedly(Return(S_OK));

    sut_->Add(deviceMock_.get(), 90);
}

因为我只在 Effect::Add() 中传递一个原始指针(模拟)deviceMock_.get(),引用计数不会增加。测试比实际 SUT 更早拆除,因此在调用 Effect 析构函数时 deviceMock_ 已被删除。我的问题是..设备仍在 Effect 的析构函数中被调用,因此导致崩溃:

(*it)->device->Remove(this, (*it)->position);

关于在调用 ~Effect 时我可以做些什么来强制 deviceMock_ 保持活动状态的任何想法? 我可以强制 deviceMock_ 引用计数仅使用原始指针递增吗 Device* device??

请注意,我无法更改函数签名 OF:

HRESULT Effect::Add(Device* device, ULONG position)

因为这是 API.

请帮忙!谢谢!

颠倒EffectTestsut_deviceMock_的顺序:

class EffectTest: public ::testing::Test
{
public:
    void SetUp()
    {
        sut_ = std::make_unique<Effect>();
        deviceMock_ = std::make_shared<DeviceMock>();
    }

protected:
    std::shared_ptr<DeviceMock> deviceMock_;
    std::unique_ptr<Effect> sut_;
};

成员变量从下往上删除。更改此项将导致 Effect 在 DeviceMock 之前被删除。

我终于想出了解决这个问题的方法。基本上,我将 sut_ 的范围从 class 级别更改为测试级别:

class EffectTest: public ::testing::Test
{
public:
    void SetUp()
    {
        deviceMock_ = std::make_shared<DeviceMock>();
    }

protected:
    std::shared_ptr<DeviceMock> deviceMock_;
};


TEST_F(EffectTest, Add)
{
    auto sut_ = std::make_unique<Effect>();  //THIS IS THE FIX!

    EXPECT_CALL(*deviceMock_, Add(_).WillRepeatedly(Return(S_OK));
    EXPECT_CALL(*deviceMock_, Remove(_, _)).WillRepeatedly(Return(S_OK));

    sut_->Add(deviceMock_.get(), 90);
}

这样,sut_ 相对于 mock 首先被破坏。