C++ const应该用于捕获错误还是用于文档?
假设我有一个不可变的类C++ const应该用于捕获错误还是用于文档?,c++,constants,C++,Constants,假设我有一个不可变的类C。从用户的角度来看,我们永远无法更改任何C对象的功能行为 但是,出于性能方面的原因,假设我们有一个toString方法,该方法将对象转换为字符串并返回它。我不想每次都要做这个计算,所以我将结果存储在一个成员变量中,这样如果用户再次调用toString,它会很快 我是否要使用toString函数const(并且只使用const\u cast来存储结果),因为只要我们将接口与实现分离,toString就应该被视为不修改对象,或者我应该将其设置为非const,因为它将帮助编译器
C
。从用户的角度来看,我们永远无法更改任何C
对象的功能行为
但是,出于性能方面的原因,假设我们有一个toString
方法,该方法将对象转换为字符串并返回它。我不想每次都要做这个计算,所以我将结果存储在一个成员变量中,这样如果用户再次调用toString
,它会很快
我是否要使用
toString
函数const
(并且只使用const\u cast
来存储结果),因为只要我们将接口与实现分离,toString
就应该被视为不修改对象,或者我应该将其设置为非const,因为它将帮助编译器捕捉错误?为什么corect答案最终会出现在注释中
有这样的功能是可以的。这种方法在“inspect()成员函数的尾部const应该用来表示该方法不会更改对象的抽象(客户端可见)状态”中给出。只是不要使用const_cast,而是mutable,请参见。拥有const对象的目的是保证它不会在某个例程过程中被更改。这完全是为了向其他开发人员传达您的意图,并向优化器提供信息,因为const不存在于机器代码级别 Const对象只允许调用Const方法,否则,声明为Const的对象可能会通过调用其方法之一而改变其值,这首先会破坏它是Const的观点。因此,在编写类时,最好尽可能将方法标记为const,以便该类的const对象可以调用这些方法 有几个实现可以满足您的需求。鉴于我对您当前的需求知之甚少,这里有一个设计应该适合您。这将在构造函数中创建字符串,因为即使对象声明为const,构造函数也可以修改该对象。然后,每当调用toString()并且不需要可变关键字时,它就会检索预填充的字符串(在第二个示例中详细介绍)。我希望你不介意我对构造什么样的字符串以及应该在其中包含什么所做的自由
class ImmutableClass
{
private:
std::string strTextRepresentation;
public:
int nValue1, nValue2, nValue3; //variables that are to be used in the string
ImmutableClass(int nValue1, int nValue2, int nValue3):
nValue1(nValue1), nValue2(nValue2), nValue3(nValue3)
{
std::stringstream ss;
ss << nValue1 << ',' << nValue2 << ',' << nValue3;
strTextRepresentation = ss.str();
}
const std::string& toString() const
{
return strTextRepresentation;
}
};
类不可变类
{
私人:
std::字符串strTextRepresentation;
公众:
int nValue1、nValue2、nValue3;//字符串中要使用的变量
ImmutableClass(int nValue1、int nValue2、int nValue3):
nValue1(nValue1)、nValue2(nValue2)、nValue3(nValue3)
{
std::stringstream-ss;
ssConst有多种用法,首先,Const对于文档来说很重要。我知道人们不同意这一点,尽管它清楚地显示了成员函数的意图或函数的参数
第二,它可以防止错误,当您指明了意图并且碰巧调用了错误的函数(非常量)时,这将导致编译错误。因此,要么您的意图是错误的,要么不应该调用该函数
最后,该规则也有例外。每当您有一些延迟实现时,您应该使用mutable,因为在调整常量casted是未定义的行为(隐藏在单个函数实现中)时,允许调整可变成员(在所有转换单元中都是已知的,因为在头文件中).就个人而言,我对使用mutable有混合的感觉,因为在多线程处理中必须小心。(因此,您需要正确的锁定,std::call_once…或者您需要知道这不是在多线程代码中调用的)
有关常量转换和可变的更多详细信息,请参见7.1.6.1和5.2.11中的标准
除了任何声明为可变(7.1.1)的类成员都可以修改外,任何在常量对象的生存期(3.8)内修改常量对象的尝试都会导致未定义的行为
通常人们会通过const来引用优化。虽然这实际上比你想象的要难。我一直在遵循clang编译器:
您可以看到,目前只实现了概念验证。(我不熟悉其他实现)
因此,总而言之:
- Const用于文档和防止错误
- 使用常量上的可变项
最好用一些代码问这个问题。更好的方法是使成员变量可变
或者,您可以将对象与其缓存解耦,在一组对象之间共享缓存[可能是不同类型的。将其设置为常量将有助于编译器捕获错误。将其设置为非常量则不会。你的问题没有意义,也与你的标题无关。
class ImmutableClass
{
private:
mutable std::string strTextRepresentation;
public:
int nValue1, nValue2, nValue3; //variables that are to be used in the string
ImmutableClass(int nValue1, int nValue2, int nValue3):
nValue1(nValue1), nValue2(nValue2), nValue3(nValue3)
{
}
const std::string& toString() const
{
//NOTE: consider using another kind of check for if the string
//has been set. I recommend an optional<T> wrapper (easy to implement, or see the boost library)
if (strTextRepresentation.size() == 0)
{
std::stringstream ss;
ss << nValue1 << ',' << nValue2 << ',' << nValue3;
strTextRepresentation = ss.str();
}
return strTextRepresentation;
}
};