在编写我在空闲时间开发的个人软件时,我经常感到需要C ++中的功能,因此只能保护函数中的特定类变量不被修改。
编辑:以下示例说明具体用例不正确。请参考问题底部的EDIT部分。保持代码与现有答案保持一致。
class Circle
{
private:
double radius;
double area;
public:
void setRadius(double r);
double getArea();
};
void Circle::setRadius(double r)
{
radius = r;
}
double Circle::getArea()
{
area = 3.142 * radius * radius;
return area;
}
这是一个非常简单的例子,仅仅是为了解释这个问题。
现在在getArea()
我想阻止修改radius
。
但我无法使getArea() const
功能,因为area
已在其中修改。
有些人可能会说这是我的愚蠢编程,但有时我发现自己处于这种情况。这确实有助于在开发阶段本身防止错误。如果C ++无法做到这一点,那么请提供宝贵的建议来解决问题。
编辑:在此示例中,getArea()
中涉及的计算非常少,因为它仅依赖于radius
,但有时可能依赖于许多变量。
如果在获得area
之前需要修改所有变量,则每个变量的setter函数中的计算区域将导致不必要的计算。计算area
的值可能是计算密集型的,因此将结果值存储为类变量是一种避免重新计算的好方法,如果多次调用area
的getter。在这种情况下,以下问题是有效的:
我需要修改const函数中的类变量。我该怎么办 是什么?
答案 0 :(得分:5)
您应该在area
内计算setRadius()
,因为area
和radius
之间的关系是固定的,并且是类不变的。
然后getArea()
只需要return area;
即可const
。
这种职责分离(设置者维护类不变量,getter只返回内部状态)是getter和setter的目的。
修改:另请注意,在此示例中,您并不需要area
成为班级成员。您可以按如下方式定义您的类:
class Circle
{
private:
double radius;
public:
void setRadius(double r);
double getArea() const;
};
void Circle::setRadius(double r)
{
radius = r;
}
double Circle::getArea() const
{
double area = 3.142 * radius * radius;
return area;
}
通过将area
作为方法的局部变量而不是类成员,该方法可以保持const
。
正如其他人所说,还有一个mutable
关键字可以应用于area
。如果修改变量不会改变类的向外含义,这将非常有用。它对于延迟初始化或维护内部统计信息非常有用。
但是,通常情况下,如果一个类的属性和不变量被预先维护,则更容易推理出来。
答案 1 :(得分:2)
您可以area
成为mutable
,并标记getArea() const
:
mutable double area;
double Circle::getArea() const
{
area = 3.142 * radius * radius;
return area;
}
这是数据成员延迟初始化的常用习惯用法,通常在所述数据成员构建成本高时使用。
在这种情况下,根本不清楚缓存area
会带来什么好处。您可以通过删除area
数据成员并返回结果来回避问题
double Circle::getArea() const
{
return 3.142 * radius * radius;
}
答案 2 :(得分:1)
有些人可能会说这是我的愚蠢编程,但有时候我会发现自己处于这种情况。
是的,它是,你不应该。
如果您发现必须缓存此类计算,请在计算组件因子并且在getter中不时执行此操作。 (坦率地说,在这种情况下,我根本不会存储area
。)
const
规则试图告诉你这个。
答案 3 :(得分:0)
正如其他人所指出的那样,你不应该存储area
。决定您所谈论的圈子的仅仅是radius
。
如果您将area
声明为成员,那么您将失去以下内容:
const
限定符,如您所述。vector
中,则无意中将存储需求加倍,无法将对象加载到单个缓存行中。我知道您的Circle
课程确实是说明性的,但请尝试将这种思维方式转换为您的项目。