C ++ map [] =内存分支

时间:2019-06-02 04:07:05

标签: c++ memory

假设您有一个无序的实例变量映射,该映射将一个整数映射到一个对象(如时间对象)。 如果要覆盖该地图,并且在类函数中使用了诸如map_ [5] = time.now()的标准覆盖,那么time.now对象将在哪里创建?它是否在函数所在的堆栈中,所以当函数超出范围时,映射中的时间就会超出范围?还是使用类对象,以便您以后可以检查时间?

基本上,如果您在一个函数中编写实例字段映射,并且存储了以后要访问的对象,您可以使用普通对象还是需要使用指针?

我已经有一段时间没有使用C ++了,我试图重新学习细微差别,这确实使我感到困惑。谢谢!

1 个答案:

答案 0 :(得分:2)

std::mapstd::unordered_map中包含的对象的生存期是映射的生存期。请记住,尽管您分配给地图元素的对象与地图中包含的对象不是同一对象。


例如,在此片段中:

std::map<int, std::chrono::system_clock::time_point> my_map;
auto now = std::chrono::system_clock::now();
my_map[10] = now;

实际上至少涉及两个time_point对象:

  1. now
  2. my_map[10]

my_map[10] = now行实际上做了很多:

  1. 由于my_map中的键10不存在任何值,因此map::operator[]默认构造一个新的time_point对象,将其插入my_map中并返回对此的引用。
  2. 调用返回的time_point对象的赋值运算符函数,并将其传递给now的引用。
  3. time_point::operator=调整被调用的time_point的状态,以反映传递给它的time_point的状态。

存储在地图中的time_point对象的生命周期由地图控制。 now是一个局部变量,因此其生存期将在声明该变量的作用域的结尾处结束。


例如,给定以下类定义:

class Foo {
public:
    const std::chrono::system_clock::time_point& do_a_thing(int i);
private:
    std::map<int, std::chrono::system_clock::time_point> my_map;
};

以下do_a_thing的定义无效:

const std::chrono::system_clock::time_point& do_a_thing(int i) {
    auto now = std::chrono::system_clock::now();
    my_map[i] = now;
    return now;  // whoops, returning a reference to a function local
}

以下内容有效:

const std::chrono::system_clock::time_point& do_a_thing(int i) {
    auto now = std::chrono::system_clock::now();
    my_map[i] = now;
    return my_map[i]; // OK, the lifetime of my_map[i] is the same as my_map
}