在单元测试中初始化 unique_ptr

Posted

技术标签:

【中文标题】在单元测试中初始化 unique_ptr【英文标题】:Initialise unique_ptr in the unit tests 【发布时间】:2016-05-17 15:18:36 【问题描述】:

我有以下代码:

class foo 

    public:
        foo();
        void setMean(std::shared_ptr<std::valarray<double>> input);
    private:

        std::shared_ptr<std::valarray<double>> mean;


.cpp 文件:

foo::foo() : mean(nullptr) 


void foo::setMean(std::shared_ptr<std::valarray<double>> input)
    mean = input;

现在,在单元测试文件中:

std::shared_ptr<std::valarray<double>> input = std::make_shared<std::valarray<double>>(std::initializer_list<double>0.0, 0.0);

std::unique_ptr<foo> meanObj;

meanObj->setMean(input);

当控件进入setMean 函数时,代码会中断。

unique_ptr的初始化有问题吗?

【问题讨论】:

你在哪里初始化meanObj 实际上没有 foo 对象 为什么还需要unique_ptr?就做foo meanObj; meanObj.setMean(input); 【参考方案1】:

使用原始指针重写的示例的最后两行将是

foo* meanObj = nullptr;
meanObj->setMean(input);

你看到问题了吗?您正在取消引用 nullptr。您需要先创建一个由unique_ptr 管理的foo 对象

auto meanObj(std::make_unique<foo>());
// or std::unique_ptr<foo> meanObj(new foo);
meanObj->setMean(input);

【讨论】:

感谢您的回答。出于某种原因,我不能使用std::make_unique。但是使用替代方法,它可以工作。 @chintans make_unique 是在 C++14 中添加的,因此您需要一个支持该版本的 stdlib 实现。【参考方案2】:

是的,你在哪里初始化std::unique_ptr

你不是,这就是为什么std::unique_ptr 将指向nullptr,你不能尊重它,所以你遇到了分段错误。

std::make_unique初始化它:

std::unique_ptr<foo> meanObj = std::make_unique<foo>();

【讨论】:

【参考方案3】:

是的,有。你需要用一个实际的对象来初始化它,像这样:

std::unique_ptr<foo> meanObj(std::make_unique<foo>());

没有这个,您将调用std::unique_ptr 的默认构造函数,它将指向的基础成员设置为nullptr。因此,您对下一行的尊重是一个空指针取消引用。

【讨论】:

【参考方案4】:

您没有设置meanObj 指向/拥有任何东西。您需要使用foo 对象初始化智能指针。

如果你不使用 C++14 并且你不想在你声明它的地方初始化你的 unique_ptr,你可以这样做

meanObj.reset( new foo() );

【讨论】:

【参考方案5】:

我知道您已经接受了答案,但据我所知,您根本不需要使用 unique_ptr。只需使用对象本身:

foo meanObj;
meanObj.setMean(input);

【讨论】:

我贴的代码是精简版,实际代码太复杂了。

以上是关于在单元测试中初始化 unique_ptr的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 单元测试中,我在 App 和单元测试目标之间遇到类转换错误

java怎么做单元测试,紧急!

聊聊单元测试——Spring Test+JUnit完美组合

测试驱动开发 (TDD):在 Xcode 4 中编写单元测试

聊聊单元测试——Spring Test+JUnit完美组合

iPhone Nibs 如何使用逻辑测试进行单元测试?