c ++填充std :: map创建不必要的对象

Wer*_*rem 1 c++ stdmap

我有一个动画,在默认构造函数,析构函数和另一个构造函数中打印一些独特的字符串:

class Animation{
public:
   int x;
   Animation(int x) {
        std::cout << "+ animation\n";
    }

    Animation() {
        std::cout << "+ animation\n";
    }

    ~Animation() {
    std::cout << "- animation\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

我想用这个对象填充std :: map,std :: map定义是这样的:

std::map<int, Animation> animations;
Run Code Online (Sandbox Code Playgroud)

当我尝试填充地图时,我这样做

void createAnimations(){
    animations[0] = Animation(10);
    animations[1] = Animation(10);
    animations[2] = Animation(10);
    animations[3] = Animation(10);
    animations[4] = Animation(10);
}
Run Code Online (Sandbox Code Playgroud)

当我运行程序时,打印出来

+ *animation
+ animation
- animation
+ *animation
+ animation
- animation
+ *animation
+ animation
- animation
+ *animation
+ animation
- animation
+ *animation
+ animation
- animation
Run Code Online (Sandbox Code Playgroud)

为什么要创建和销毁这些额外的对象?

Xir*_*ema 5

在尝试分配之前,使用a的括号运算符std::map或std::unordered_map导致创建条目(使用其默认构造函数).

考虑这样的陈述可能会更好:

animations[0] //operator[] invoked; default-constructed object created
= //Assignment operator
Animation(10); //Animation object constructed using Animation(int) constructor.
               //Was created as an X-value, will be move-assigned into the default-constructed object
Run Code Online (Sandbox Code Playgroud)

如果要在没有调用默认构造函数的情况下插入到地图中,则需要使用insert或emplace:

//May invoke move-constructor, may be elided, depending on how aggressively your compiler optimizes
animations.insert(std::make_pair(0, Animation(10));
animations.insert(std::make_pair(1, Animation(10));
animations.insert(std::make_pair(2, Animation(10));
animations.insert(std::make_pair(3, Animation(10));
animations.insert(std::make_pair(4, Animation(10));

//Will construct in-place, guaranteeing only one creation of the object
//Necessary if the object cannot be move or copy constructed/assigned
animations.emplace(0, 10);
animations.emplace(1, 10);
animations.emplace(2, 10);
animations.emplace(3, 10);
animations.emplace(4, 10);
Run Code Online (Sandbox Code Playgroud)

  • @Werem将您的新代码发布为新问题. (2认同)