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;
}
答案 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