返回指针向量

时间:2015-10-14 13:21:29

标签: 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;
    }
};

问题是我想阻止更改参数项中指针指向的值。但是使用从getItems返回的向量,我可以更改指向的值。

现在,为了解决这个问题,我可以将参数项声明为vector<const int*>但是我无法更改我的类中的值。 有没有其他方法来保护值,但仍然没有在items声明中使用const?

2 个答案:

答案 0 :(得分:5)

正如 @KerrekSB 指出的那样,您需要重建结构,将元素的类型更改为常量:

std::vector<const int*> getItems() const { 
    return std::vector<const int*>(items.begin(), items.end());
}

此处vector<const int*>的构造函数使用从int*const int*的隐式转换。您不能在此处返回items,因为vector<T>在{T}上为invariant。这直接意味着无法从vector<int*>转换为vector<const int*>通过类型演员。

解决你的意见:

  

这是唯一的方法吗?我觉得创建副本效率很低。

对于副本,它只复制指针数据,因此每个元素通常为8个字节。对于指向较大结构的指针向量,它通常可以忽略不计,但对于int s的向量,它确实是一个相当大的开销。

这给我们带来了一个问题:为什么你首先存储指针?只需存储vector<int>,然后您就可以向其返回const&

答案 1 :(得分:5)

如果您想避免复制并允许对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);   
    }
};

然后,您将使用该迭代器遍历Bag内容,而不是获取整个vector项。如果您提供了beginend功能,那么您甚至可以使用基于范围的for循环。