【问题标题】:Returning a reference to an element of a class member container返回对类成员容器元素的引用
【发布时间】:2015-01-30 09:50:55
【问题描述】:

Foo 的行为类似于循环迭代器。尽管我对此感到紧张,但下面的代码编译得很好,但会产生运行时错误。即使我从 get_current() 中删除了 const,我也会收到错误消息。当然,我可以返回一个指针,它会起作用;但是,我会在返回引用时获得更好的安全性吗?

#include <iostream>
#include <array>
#include <memory>

class Foo
{
public:
  Foo();
  void next();
  const int& get_current() const;
private:
  std::array<std::unique_ptr<int>, 3> arr_;
  unsigned i_;
};

Foo::Foo() : i_(0)
{
  arr_[0] = std::unique_ptr<int>(new int(5));
  arr_[1] = std::unique_ptr<int>(new int(6));
  arr_[2] = std::unique_ptr<int>(new int(7));
}

void Foo::next()
{
  ++i_;
  i_ %= 3;
}

const int& Foo::get_current() const 
{
  return *arr_[i_];
}

int main()
{
  Foo foo;
  int* p;

  *p = foo.get_current();
  //do something with p
  std::cout << *p << std::endl;

  foo.next();
  *p = foo.get_current();
  //do something with p
  std::cout << *p << std::endl;

  return 0;
}

【问题讨论】:

    标签: c++ class pointers reference member


    【解决方案1】:
    int* p;
    

    这是一个未初始化的指针,没有指向任何东西。取消引用它会产生未定义的行为。

    *p = foo.get_current();
    

    取消引用无效指针。轰隆隆!

    也许你希望它指向数组元素

    p = &foo.get_current();
    

    或者你可能想要一个数组元素的副本

    int n;
    n = foo.get_current();
    

    【讨论】:

      【解决方案2】:

      foo.get_current(); 很可能会返回一个const 引用,但之后您在分配给*p 时尝试获取该引用的 副本。

      分配给*p 是给您带来麻烦的原因,因为p 未初始化。这是未定义的行为,在您的情况下表现为运行时错误。

      可以使用const int&amp; p = foo.get_current(); 之类的代码,但请注意,引用只能绑定一次,因此您必须小心范围。

      或者,您可以使用std::shared_ptr&lt;int&gt; 并将其设为get_current() 的返回类型,并完全去除您的代码中的裸指针。

      【讨论】:

        【解决方案3】:

        *p = ... 在未正确初始化的情况下取消引用 int* P

        将 main 中的代码更改为

         int p; // Remove *
        
         p = foo.get_current();
         //do something with p
         std::cout << p << std::endl;
        

        或者如果你真的想使用指针

         const int* p;
        
         p = &foo.get_current();
          // ^ Take the address
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多