作者:手机用户2702934045 | 来源:互联网 | 2022-12-10 09:46
我们来看以下源代码:
const ushort *QString::utf16() const
{
if (IS_RAW_DATA(d)) {
// ensure '\0'-termination for ::fromRawData strings
const_cast(this)->reallocData(uint(d->size) + 1u);
}
return d->data();
}
reallocData()修改d指针类成员d,请参阅https://code.woboq.org/qt5/qtbase/src/corelib/tools/qstring.cpp.html#_ZN7QString11reallocDataEjb.如果QString对象是const怎么办?根据https://en.cppreference.com/w/cpp/language/const_cast修改const对象并抛弃constness是UB:
struct type {
int i;
type(): i(3) {}
void f(int v) const {
const_cast(this)->i = v; // OK as long as the type object isn't const
}
};
type t; // if this was const type t, then t.f(4) would be undefined behavior
t.f(4);
我们在这段特殊代码中有UB(QString :: utf16())吗?
1> user7860670..:
如果QString
调用此方法的对象是const限定的,那么这确实是一个UB :
QString const str{"whatever"};
str.utf16();
请注意,这里的重要部分是对象是const限定的,而不是该方法是const限定的.
这也是我使用`mutable`而不是`const_cast`业务来限定`d`的原因.
@Martin不再是你想要的其他变量.注意当前的`const_cast`并没有更好.这样做的想法是,缓存变量的创建在内部是互斥的,但它只运行一次(直到底层对象实际被改变,在这种情况下,所有的投注都是关闭的).在任何情况下,`QString`和大多数其他Qt容器都不是真正的好例子.