非指针向量的 getter 的常量正确性

问题描述 投票:0回答:1

我有一个关于非指针向量的 getter 的常量正确性的快速问题。

基本上,我的这个类有一个非常量 getter 和一个 const getter

m_Vertices
:

class Mesh
{
public:
    std::vector<Vertex>& GetVertices() { return m_Vertices; }

    const std::vector<Vertex>& GetVertices() const { return m_Vertices; }

private:
    std::vector<Vertex> m_Vertices;
}

非常量 getter 是有道理的 —— getter 是非常量的,我们返回一个对非常量

Vertex
实例向量的非常量引用。

另一方面, const getter 对我来说没有意义。我质疑常量的正确性以及我是否应该返回向量的副本。我看到的问题是我们返回一个对 non-const

Vertex
实例向量的 const 引用。因此,被调用者将拥有对
m_Vertices
的 const 引用,但仍然能够修改
Vertex
实例,这在 const 正确性方面对我来说是错误的。

在这种情况下,我应该只返回一份

m_Vertices
的副本吗?

谢谢你,

安东尼

c++ vector reference getter const-correctness
1个回答
1
投票

首先要明白这是一个基于意见的问题。当你设计一个关于 const 的使用的类时,没有正确或错误的答案。

但是,在这种情况下,您的 const 声明是合理的。特别是你的陈述“被调用者将具有对 m_Vertices 的 const 引用,但仍然能够修改 Vertex 实例”是不正确的 - 因为在

std::vector
的实现中做出了关于常量性的决定。

人们可能想通过三种主要方式来修改向量及其元素。被调用者可能想要从向量中添加/删除项目,可能想要更改元素字段的值,或者可能想要替换元素之一。对 const 向量的引用将使所有这三个操作出错:

#include <iostream>
#include <vector>
#include <span>

struct point {
    double x;
    double y;
};

class vertices {
    std::vector<point> points_;
public:
    vertices(std::span<const point> pts) :
        points_{pts.begin(), pts.end()}
    {}

    const std::vector<point>& get() const {
        return points_;
    }

    std::vector<point>& get() {
        return points_;
    }
};

int main()
{
    vertices verts({ { {1.0,2.0}, {3.0,4.0}, {5.0,6.0}} });
    const auto& const_verts = verts;

    verts.get().push_back({ 7.0,8.0 }); // <= yes.
    //const_verts.get().push_back({ 7.0,8.0 }); <= no

    verts.get().front().x += 1; // <= yes.
    //const_verts.front().x += 1; // <= also no

    verts.get()[0] = { 0.0,0.0 }; // <= yes.
    //const_verts.get()[0] = { 0.0,0.0 }; <= no
}
© www.soinside.com 2019 - 2024. All rights reserved.