返回对类成员容器的元素的引用

时间:2014-12-02 08:04:14

标签: c++ class pointers reference member

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

#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;
}

3 个答案:

答案 0 :(得分:2)

int* p;

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

*p = foo.get_current();

取消引用无效指针。吊杆!

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

p = &foo.get_current();

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

int n;
n = foo.get_current();

答案 1 :(得分:2)

foo.get_current();可能会返回const引用,但之后您在分配给{{1}时尝试获取副本}。

分配给*p会导致您遇到麻烦,因为*p 未初始化。这是未定义的行为,并且在您的情况下表现为运行时错误。

可以使用像p这样的代码,但要注意引用只能绑定一次,所以你必须小心使用范围。

,您可以使用const int& p = foo.get_current();并将其作为std::shared_ptr<int>的返回类型,并完全剥离您的代码。

答案 2 :(得分:1)

*p = ...您取消引用int* P而未正确初始化。

将您的代码更改为

 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