Ada*_*dam 9 c++ pointers stl const
说我有这个班:
#include <vector>
using namespace std;
class Bag
{
vector<int*> items;
public:
void addItem(int* i)
{
items.push_back(i);
}
const vector<int*> getItems() const
{
return items;
}
};
Run Code Online (Sandbox Code Playgroud)
问题是我想阻止参数项中指针指向的值的更改.但是使用从getItems
我返回的向量允许更改指向的值.
现在,为了解决这个问题,我可以将参数项声明为,vector<const int*>
但是我也无法更改我的类中的值.有没有其他方法来保护值但仍未在项目声明中使用const?
正如@KerrekSB指出的那样,您需要重构结构,将元素的类型更改为const 元素:
std::vector<const int*> getItems() const {
return std::vector<const int*>(items.begin(), items.end());
}
Run Code Online (Sandbox Code Playgroud)
这里的构造vector<const int*>
采用从隐式转换int*
到const int*
.你不能只返回items
这里,因为在T上vector<T>
是不变的.这直接意味着没有办法转换vector<int*>
为vector<const int*>
仅仅通过类型转换.
解决你的评论:
这是唯一的方法吗?我觉得创建副本效率低下.
至于副本,它只复制指针数据,因此通常每个元素8个字节.对于指向较大结构的指针向量,它通常可以忽略不计,但对于int
s 的向量,它确实是一个相当大的开销.
这带来了一个问题:为什么你首先存储指针?只需存储vector<int>
,然后您就可以返回const&
它.
如果您想避免复制并允许对std::vector
元素进行只读访问,则可以提供const_iterator
进入容器的函数:
class Bag
{
vector<int*> items;
public:
void addItem(int* i)
{
items.push_back(i);
}
//could just be called begin if that gives the correct idea
vector<int*>::const_iterator itemsBegin() const
{
return std::cbegin(items);
}
vector<int*>::const_iterator itemsEnd() const
{
return std::cend(items);
}
};
Run Code Online (Sandbox Code Playgroud)
然后,您将Bag
使用该迭代器循环遍历内容,而不是获取整个vector
项目.如果你提供的begin
与end
功能,那么你甚至可以使用基于范围的for循环.