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

发布于 2024-08-25 04:13:05 字数 318 浏览 9 评论 0原文

我有一个类,它有一个私有属性向量 rectVec;

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

我的问题是如何返回矢量的“只读”副本? 我正在考虑这样做:

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

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

I have a class which has a private attribute vector 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:

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

挽袖吟 2024-09-01 04:13:05

这是正确的方法,尽管您可能也希望将函数设为 const。

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

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

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

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

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

放我走吧 2024-09-01 04:13:05

这是正常的方式。 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

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

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:

int_vec& v = const_cast<int_vec&>(f.get()); // this is okay
v[0] = 0; // but now we've entered undefined behavior
指尖上的星空 2024-09-01 04:13:05

我知道它是一篇相当旧的文章,但它是搜索“c++只读向量”时最热门的谷歌结果之一。这就是为什么我想发布我的方法。

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

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

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

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.

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

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.

世界等同你 2024-09-01 04:13:05

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

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

笑脸一如从前 2024-09-01 04:13:05

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

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.

‘画卷フ 2024-09-01 04:13:05

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

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)

鹿港巷口少年归 2024-09-01 04:13:05

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文