如何返回向量的“只读”副本

时间:2010-03-17 20:44:38

标签: c++ const-correctness

我有一个具有私有属性向量rectVec;

的类
class A {
private:
   vector<Rect> rectVec;
};

我的问题是如何返回我的Vector的“只读”副本? 我在想这样做:

class A {
public:
  const vect<Rect>& getRectVec() { return rectVect; }
}

这是正确的方法吗? 我在想这可以防止被调用者修改向量(在向量中添加/删除Rect),向量中的Rect怎么样?

7 个答案:

答案 0 :(得分:28)

这是正确的方法,尽管您可能也希望创建函数const

class A {
public:
  const vect<Rect>& getRectVec() const { return rectVect; }                           
};

这使得人们可以使用getRectVec对象来呼叫const A

答案 1 :(得分:6)

这是正常的方式。 const表示“您无法修改此内容”。它也适用于容器中的元素。

一个简单的测试:

#include <vector>

typedef std::vector<int> int_vec;

struct foo
{
    const int_vec& get(void)
    {
        return v;
    }

    int_vec v;
};

int main(void)
{
    foo f;
    f.v.push_back(1);
    f.v.push_back(2);
    f.v.push_back(3);

    f.get()[0] = 2; // nope
}

const_cast可用于剥离const,但如果您通过它修改了变量,则最终会出现未定义的行为:

int_vec& v = const_cast<int_vec&>(f.get()); // this is okay
v[0] = 0; // but now we've entered undefined behavior

答案 2 :(得分:2)

这是正确的方法,除非用户使用const_cast强制转换常量。

答案 3 :(得分:2)

总的来说,这是不好的做法。您正在向调用者公开您的内部实现。你最好返回一个包装器类实例(前面提到过)或者暴露获取项目或迭代器的函数(typedefed以匹配你的实现)

答案 4 :(得分:1)

如何而不是返回对向量的引用,返回一个包装向量的新类型(包含对向量的const引用),并且只公开您希望允许调用者访问的功能。我猜这并不多,因为你想防止矢量的可变性。

答案 5 :(得分:1)

我知道它是一个相当古老的帖子,但它是搜索&#34; c ++只读矢量&#34;时的顶级谷歌搜索结果之一。这就是为什么我想发布我的方法。

如果您希望容器本身是const而不是其元素,您可以使用类似于此的方法:

template<class Container>
class Enumerable
{
public:
    Enumerable(Container& container) : _container(container) {}

    auto begin() const { return _container.begin(); }
    auto end() const { return _container.end(); }

    const Container& GetContainer() const { return _container; }
    const Container* operator->() const { return &_container; }

private:
    Container& _container;
};

使用它可以迭代容器并修改其元素,同时确保容器本身保持不变。您可能希望通过专门化类来展示容器的更多功能,例如向量提供索引运算符。

我不完全确定它是否有良好的设计来暴露这样的容器,但它绝对是一些有用的模式。

答案 6 :(得分:0)

所以基本上,使用“const&amp;”应该向任何C ++程序员表明:你真的不应该修改它。如果你真的是偏执狂,你就必须克隆这个载体。