重写 const 函数以修改 C++ 中的类变量
Override const function to modify a class variable in C++?
在编写我在空闲时间开发的个人软件时,我经常觉得需要C++功能,以便只有函数中的特定类变量必须被保护不被修改。
编辑:以下示例不正确,无法解释特定的用例。请参考问题底部的"编辑"部分。保持代码只是为了与现有答案保持一致。
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 函数中的类变量。我该怎么做 那?
你应该在setRadius()
内部计算area
,因为area
和radius
之间的关系是固定的,并且是一个类不变量。
然后getArea()
只需要return area;
就可以const
.
这种职责分离(二传手保持类不变性,二传手只是返回内部状态(是获取者和二传手的目的。
编辑:另请注意,在此示例中,您不需要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
。 如果修改变量不会更改类的外部含义,这将非常有用。 它可用于延迟初始化或维护内部统计信息。
但是,通常情况下,如果预先维护类的属性和不变量,则更容易推理它们。
你可以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;
}
有些人可能会说这是我愚蠢的编程,但有时我发现自己处于这种情况。
是的,是的,你不应该。
如果您发现必须缓存此类计算,请在计算组件因子时而不是在 getter 中执行此操作。(坦率地说,在这种情况下,我根本不会存储area
。
const
规则试图告诉你这一点。
正如其他人指出的那样,您不应该存储area
。决定你在说什么圈子的只是radius
.
如果您将area
声明为会员,您将失去以下损失:
- 正如您所指出的,您的 getter 函数上的
const
限定符。 - CPU <>内存 IO,因为每当尝试读取区域时,您都会系统地尝试更新对象数据中的区域。内存访问采用 EONS。在每次访问时重新计算面积确实比从内存中获取面积要快得多。
- 内存布局的紧凑性。如果您将结构放在
vector
中,您将无用地将存储需求加倍,失去将两倍的对象加载到单个缓存行中的机会。
我知道你的Circle
课真的很说明问题,但试着把这种思维方式应用到你的项目中。
- 查找后更改类变量
- 如何避免在仅标头库中C++类/变量重定义
- c++ 在非类函数中使用类变量
- 基于模板的类变量
- 分段 访问私有类变量时出错
- 为什么从另一个构造函数内部调用C++构造函数不修改类变量?
- 如何访问基类向量中的子类变量?(对于实体组件系统)
- 模板类变量作为非模板类的成员
- C++11 - 获取编译时的所有类变量,并在没有 Boost 的情况下为它们调用方法
- 如何在构造函数中访问类变量以分配它们,而无需在C++中使用此指针
- 类变量无法从类方法访问
- 指针作为类变量 Qt
- 为什么线程对类变量所做的更改没有影响?
- memcpy() 在一个类中被调用以复制到另一个类变量中后会引发异常
- C++:使用基类中的仅派生类变量
- 从静态成员函数访问私有非静态类变量 - C++
- 静态类变量的多重定义
- 使用 WindowSetup 类变量获取错误
- 将文本文件读入类变量 - c++
- 获取作为类变量的 Deque 大小时未定义的行为