使用C++关键字的建议"const"

Advice for using "const" keyword of C++

本文关键字:const C++ 关键字 使用      更新时间:2023-10-16

我正在为Vector3和Quaternion编写类。这是我的代码:

// .h file
Quaternion operator * (const Vector3& v) const;
// .cpp file
Quaternion Quaternion::operator * (const Vector3& v) const
{
    float s = -(m_v.dot(v));
    Vector3 vt = (v*m_s) + m_v.cross(v);
    return Quaternion(s, vt.getX(), vt.getY(), vt.getZ());
}

由于我在Vector3.h中这样声明:,所以"return"行出现错误

float&  getX();
float&  getY();
float&  getZ();

我想我可以通过这样的声明来通过这个案子:

const float&    getX() const;
const float&    getY() const;
const float&    getZ() const;

我也看到我不会再使用这个了:

Vector3 v(1.0f, 2.0f, 3.0f);
v.getX()++;
// or v.getX() += 1; => coz I feel writing code like this is more readable.

并且必须这样写代码:

float x = v.getX();  // I dont like this coz it will waste memory
                     // if it's not an "float" but a big object
x += 1;
v.setX(x);

所以,我的问题是:

  1. 有什么方法可以满足这两种情况吗?或者,简单地说,这是一种选择的权衡
  2. 对于C++程序员来说,经常使用"const"关键字是一种好的做法吗

您可以提供两个不同版本的函数。

class Vector {
    public:
        float getX() const;
        float & getX();
};
void foo(const Vector & const_v, Vector & v) {
    v.getX() += 1;
    const_v.getX() += 1; // Won't work.
}

请注意,如果您的Vector只是一个数据容器,那么只需将其声明为struct并允许直接访问所有成员就更简单了。只有当对私有字段的访问应该以某种方式受到监管的可能性为零时,才应该使用getter和setter(例如,您希望Vector不断规范化,因此对字段的任何写入都应该以非常特定的方式更改所有这些)。

首先,在一般情况下,如果可能的话,您应该将所有内容标记为const。这样做可以节省以后的大量调试或文档阅读,因为编译器可以帮助诊断逻辑问题。

为了返回对私有成员的引用,C++标准库使用了具有两个重复版本的方法,一个声明为const,另一个不声明。这也可以是你的方法。

但在你的具体情况下,你可以公开这些信息。很多书告诉你总是将成员声明为私有,并使用getter和setter,因为这就是"OOP的工作原理",但事实并非如此。如果一个类只是保存数据,不提供其他抽象,那么将这些字段设为私有字段就没有任何好处。

最后,如果您非常关心效率,那么只要您实际上不需要float&,就应该返回float。后者还需要内存或寄存器分配,可能比普通float占用的内存大。访问float&还需要间接寻址,这是相当昂贵的。

在get函数中使用const是一种很好的编程实践,因为get函数应该只有读取数据的权限,而不是修改数据的权限。