我有一个关于非指针向量的 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
的副本吗?
谢谢你,
安东尼
首先要明白这是一个基于意见的问题。当你设计一个关于 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
}