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

时间:2022-09-11 16:48:38

I have a class which has a private attribute vector rectVec;

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

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

My question is how can I return a 'read-only' copy of my Vector? I am thinking of doing this:

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

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

Is that the right way? I am thinking this can guard against the callee modify the vector(add/delete Rect in vector), what about the Rect inside the vector?

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

7 个解决方案

#1


27  

That is the right way, although you'll probably want to make the function const as well.

这是正确的方法,尽管你可能也想要使函数const。

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

This makes it so that people can call getRectVec using a const A object.

这使得人们可以使用const A对象调用getRectVec。

#2


6  

That's the normal way. const means "you cannot modify this". It also applies to the elements within the container.

这是正常的方式。 const表示“你不能修改它”。它也适用于容器中的元素。

A simple test:

一个简单的测试:

#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 could be used to strip the const away, but you'd then end up with undefined behavior if you modified a variable through it:

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

#3


2  

That is the correct way, unless the user casts the constness away using const_cast.

这是正确的方法,除非用户使用const_cast转换constness。

#4


2  

in general this is bad practice. You are exposing your internal implementation to your callers. You are better of either returning a wrapper class instance (mentioned before) or exposing functions that get items or iterators (typedefed to match your implementation)

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

#5


1  

How about instead of returning a reference to your vector, return a new type that wraps the vector (contains a const reference to the vector) and exposes only the functionality you wish to allow the caller to access. I'm guessing this isn't much since you want to prevent mutability of the vector.

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

#6


1  

I know its a rather old post but its one of the top google results when searching for "c++ read only vector". Thats why I want to post my approach nevertheless.

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

If you want the container itself to be const but not its elements you can use an approach similar to this one:

如果您希望容器本身是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;
};

With that you can iterate over your container and modify its elements while ensuring the container itself stays the same. You may want to expose more functionality of the container by specializing the class for e.g. vectors by providing an indexing operator.

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

I'm not entirely sure if its good design to expose a container like that but its definitely a useful pattern for some scenarios.

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

#7


0  

So basically, using "const &" should indicate to any C++ programmer: You're really not supposed to modify this. If you're really paranoid, you'll have to clone the vector.

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

#1


27  

That is the right way, although you'll probably want to make the function const as well.

这是正确的方法,尽管你可能也想要使函数const。

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

This makes it so that people can call getRectVec using a const A object.

这使得人们可以使用const A对象调用getRectVec。

#2


6  

That's the normal way. const means "you cannot modify this". It also applies to the elements within the container.

这是正常的方式。 const表示“你不能修改它”。它也适用于容器中的元素。

A simple test:

一个简单的测试:

#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 could be used to strip the const away, but you'd then end up with undefined behavior if you modified a variable through it:

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

#3


2  

That is the correct way, unless the user casts the constness away using const_cast.

这是正确的方法,除非用户使用const_cast转换constness。

#4


2  

in general this is bad practice. You are exposing your internal implementation to your callers. You are better of either returning a wrapper class instance (mentioned before) or exposing functions that get items or iterators (typedefed to match your implementation)

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

#5


1  

How about instead of returning a reference to your vector, return a new type that wraps the vector (contains a const reference to the vector) and exposes only the functionality you wish to allow the caller to access. I'm guessing this isn't much since you want to prevent mutability of the vector.

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

#6


1  

I know its a rather old post but its one of the top google results when searching for "c++ read only vector". Thats why I want to post my approach nevertheless.

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

If you want the container itself to be const but not its elements you can use an approach similar to this one:

如果您希望容器本身是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;
};

With that you can iterate over your container and modify its elements while ensuring the container itself stays the same. You may want to expose more functionality of the container by specializing the class for e.g. vectors by providing an indexing operator.

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

I'm not entirely sure if its good design to expose a container like that but its definitely a useful pattern for some scenarios.

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

#7


0  

So basically, using "const &" should indicate to any C++ programmer: You're really not supposed to modify this. If you're really paranoid, you'll have to clone the vector.

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