【问题标题】:is this use of references incorrect?这种引用的使用不正确吗?
【发布时间】:2012-08-02 16:21:51
【问题描述】:

我有以下代码:

std::vector<A>& Get() { return some_object; };

for(int i=0; i<Get().size(); ++i) {
    x->push_back(Get()[i]);
}

但是当我第一次调用 size() 时,我得到了垃圾值。 我在想一些临时的被删除了,但我不太确定...... 谁能告诉我发生了什么?

编辑:我的some_object 是一个静态向量,所以在这个例子中它永远不会被删除

【问题讨论】:

  • 我认为我们需要知道 some_object 是什么来回答这个问题,因为答案取决于它的范围和生命周期。
  • 如果您不更改some_object,请考虑参考const。 STL 容器不是线程安全的,请确保在访问它时大小不会改变。否则请确保将变量或成员保持在范围内。
  • 可能没问题,这取决于 some_object 是什么。它是否存在于函数之外?
  • 是从静态或全局对象的构造函数内部(直接或间接)执行 for 循环吗?
  • 你应该包括some_object的声明和初始化。

标签: c++ reference temporary


【解决方案1】:

我建议替换 for 循环。我不相信 for 循环。虫子爬进来的地方太多了。

std::vector<A>& v = Get();
x.insert(x.end(), v.begin(), v.end());

【讨论】:

    【解决方案2】:

    只有两种可能——引用不正确,或者对象本身不正确。

    由于引用是对静态向量的引用,因此该引用似乎不太可能是错误的。静态对象不会消失。

    剩下的就是对象本身。是否有可能在初始化静态对象之前调用该函数?如果它是从另一个静态对象的构造函数中调用的,则可能会发生这种情况。

    【讨论】:

      【解决方案3】:

      如果您的 for 循环是在全局或静态对象的构造函数的上下文中执行的,那么您将遇到一个名为 static initialization order fiasco (SIOF) 的问题。简而言之,SIOF 意味着我们不能依赖静态对象的构建顺序。

      要解决这个问题,您可以使用construct on first use 成语。使用这个习惯用法,您可以在第一次需要静态/全局对象时懒惰地构造它们。这样可以确保在访问时会创建相互依赖的静态对象。

      对于您的示例,您可以执行以下操作:

      std::vector<A>& Get()
      {
          // 'instance' will be constructed "on demand" the first time this
          // function is called.
          static std::vector<A> instance;
          return instance;
      };
      

      这个技巧也用于实现Singleton 设计模式。

      注意:如果您的程序是多线程的,则必须使用此技巧的变体。

      【讨论】:

        【解决方案4】:

        仅当 some_object 的生命周期仅限于 Get 的主体时才不正确。

        【讨论】:

        • 哦是的,不是,基本上 some_object 是全局的
        猜你喜欢
        • 2021-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-17
        • 2016-09-22
        相关资源
        最近更新 更多