通过unique_pointer

时间:2017-08-22 18:40:45

标签: c++

我在大学的c ++项目中遇到以下问题:
我想通过使用地图存储Class1的一些对象。 由于我的项目的设计,将地图保存为成员变量的类不会创建要存储在地图中的对象。我对这个论坛的研究告诉我使用unique_ptr来传递这些对象。

将这两个想法结合在一个实验测试项目中时:

#include <iostream>
#include <memory>
#include <unordered_map>

typedef std::unique_ptr<std::string> string_ptr;

class Class1 {
public:
    std::unordered_map<std::string, string_ptr> my_unordered_map;

    Class1() : my_unordered_map(){
    }

    void addTo(string_ptr ptr) {
        std::string string = *ptr;
        std::cout << string << std::endl;
        my_unordered_map[0] = std::move(ptr);
    }
};


int main() {
    std::cout << "Process started!"<< std::endl;

    string_ptr ptr;
    ptr = std::make_unique<std::string>("text");

    Class1 cont;
    cont.addTo(std::move(ptr));


}

它编译,但抛出

  

在抛出'std :: logic_error'实例后终止调用   what():basic_string :: _ M_construct null无效

at runntime。

我也尝试按照其他帖子的建议将void addTo(string_ptr ptr)更改为addTo(string_ptr&amp; ptr),但问题仍然存在。

现在,问题是什么?是吗:
a)设计错误,不让Class1自己创建对象。在这种情况下,C++ inserting unique_ptr in map会回答我的问题 - 或 -
b)其他我对c ++的小知识让我想念?

旁注:我希望存储在这些指针中的对象不是字符串。

2 个答案:

答案 0 :(得分:2)

您的问题与unique_ptr无关。它根本与你的价值对象无关。它实际上是你的钥匙。不幸的是,整数文字0(并且只有0,而不是值为0的int变量)可以被视为任何类型的指针。而且不幸的是,std::string有一个来自char const*的隐式转换构造函数。所以当你这样做时:

my_unordered_map[0] = std::move(ptr);

由于您的密钥类型为std::string,因此您隐式地从空指针构造std::string。那是你的错误。

答案 1 :(得分:1)

下面

my_unordered_map[0] = std::move(ptr);

您将int作为密钥传递,但my_unordered_map期望std::string为关键解决方案:

my_unordered_map[string] = std::move(ptr);
  

在抛出'std :: logic_error'的实例后终止调用   what():basic_string :: _ M_construct null无效

std::string具有来自char const*的隐式转换构造函数,它意味着尝试从NULL指针构造std::string,这是导致此错误的原因。

如果您需要空字符串,请执行以下操作

my_unordered_map[std::string("")] = std::move(ptr);