分配给地图时构造的两个对象

时间:2015-07-10 18:31:18

标签: c++ arrays pointers

我试图在我的地图中存储对象,但显然当我尝试分配一个新对象时,它们被构造两次,一个被立即销毁。 有没有办法在地图中创建本地对象,还是必须存储指针?

std::map<std::wstring,Bitmap> bitmaps;
void loadBitmaps(){
    for(auto f: listdir("bitmaps")) {
        std::wcout << "loading: " << f << std::endl;
        bitmaps[f] = Bitmap(f);
        std::wcout << "loaded\n";
    }
}

这是输出:

loading: bitmap1.bmp
created with file constructor
created with empty constructor
destructed (the one with the file constructor)
loaded

3 个答案:

答案 0 :(得分:2)

首先,map为空。当您致电bitmaps[f]时,会创建密钥f的条目以及默认构造的值。这是您看到的empty constructor。所以在这种情况下:

  1. 通过Bitmap(f)
  2. 构建(临时)Bitmap实例
  3. 默认构造的位图是通过bitmaps[f]
  4. 构建的
  5. 临时位图通过Bitmap & Bitmap::operator=(Bitmap &&)Bitmap & Bitmap::operator=(Bitmap &&)分配给默认构建的位图,具体取决于位图的实现。
  6. 我建议改用bitmaps.emplace(f, f)

答案 1 :(得分:0)

std :: map operator [](key)`很特别:

  • 如果密钥存在,则返回对映射值的引用。
  • 否则,将插入具有默认构造映射类型的新对,并返回对新映射值的引用。

其他标准容器没有此行为。

您观察到插入了新的默认构造映射值,但是错过了日志记录输出中的赋值(也分析了operator =(...))。

答案 2 :(得分:0)

您的示例未使用数组,它使用的是std::mapstd::map::operator[]默认构造一个对象(如果该对象上没有对象)。要构建对象,请使用std::map::emplace

bitmaps.emplace(std::piecewise_construct, f, f);