【问题标题】:Strange behaviour for unique_pointer in Visual Studio 2010Visual Studio 2010 中 unique_pointer 的奇怪行为
【发布时间】:2026-01-11 22:25:01
【问题描述】:

我试着写这门课

#include <memory>

class ContainerUnique
{
public:

    ContainerUnique(void);
    ~ContainerUnique(void);

private:
    std::unique_ptr<UniqueElement> u;
};

其中 UniqueElement 是在别​​处定义的 POD 类。我现在这样定义构造函数体:

ContainerUnique::ContainerUnique(void)
{
    auto tmp = new UniqueElement(1);

    this->u(tmp); // u is a unique_ptr<UniqueElement>. Should this call compile?
}

而且它毫无例外地遵守。运行程序发现ContainerUnique的构造函数被调用后,u包含了一个空指针。

这是预期的行为吗?我实际调用的是什么 unique_ptr 方法?

【问题讨论】:

  • 不确定您遇到的问题。但是通过在构造函数的 initialaztrion 列表中初始化成员变量 u 来避免它们。
  • 是的,这是我在真实代码中使用的解决方案,但我仍然不确定示例中发生了什么。
  • 尝试打印自动变量的类型。不确定 typeid 是否有效。一旦你知道了类型,剩下的就很容易了。

标签: c++ visual-studio-2010 visual-c++ c++11 unique-ptr


【解决方案1】:

您正在调用default_delete&lt; UniqueElement &gt;::operator () ( UniqueElement* ptr ),因为 uniqe_ptr 派生自它(从空基类优化中受益),它删除了 ptr。尽管我不认为标准禁止这样做,但这并不是您想要的行为。

【讨论】:

    【解决方案2】:

    This is a known problem with VS2010's unique_ptr.公开从它的删除器继承,如果它是空的作为优化(空基优化)。公共继承的缺点是删除器的所有成员也成为unique_ptr 的可用成员,在本例中是删除指针的operator()(T*)

    在 VS2012 的库中修复了该错误,其中继承更改为私有。

    【讨论】:

    • 啊,你打败了我。很好的发现。
    【解决方案3】:

    应该这样做

    ContainerUnique::ContainerUnique(void):u(new UniqueElement(1)) {
    }
    

    【讨论】:

    • 这是我在生产代码中解决问题的方法,但我仍然不确定示例中发生了什么。