const_cast const 方法中的"this"将"this"分配给外部变量?

const_cast 'this' in const method to assign 'this' to outer variable?

本文关键字:const this 外部 变量 分配 cast 方法      更新时间:2023-10-16

请看下面的代码:

struct Foo;
Foo* bar;
struct Foo {
void func() const {
bar = this;
}
}
int main() {
Foo().func();
}        

这不起作用,因为bar不会接受const Foo*。为了解决这个问题,可以使用const_cast

struct Foo {
void func() const {
bar = const_cast<Foo*>(this);
}
}

这安全吗?在使用const_cast时,我非常谨慎,但在这种情况下,这对我来说似乎是合法的。

不,这是潜在的危险。

func()被标记为const,这意味着它可以由 const 对象调用:

const Foo foo;
foo.func();

因为thisconst Foo*.

如果你const_castconst,你最终会得到一个const对象的Foo*。这意味着通过非常量指针(或通过该指针的任何副本,bar在这种情况下(对该对象的任何修改都将使您获得未定义的行为,因为不允许修改const对象 (duh(。

另外,显而易见的问题是,你对类Foo的消费者撒谎,说func()不会修改任何东西,而你却在做相反的事情。

const_cast几乎从来都不正确,这对我来说似乎是一个 XY 问题。

如果"安全"是指"不是未定义的行为",那么是的,它是安全的。bar的值将按预期指向创建的对象。

但是,通常不建议使用const_cast,因为它打破了const事物不会被更改的约定,并且很容易产生未定义的行为(请参阅下面的此评论(。在这种情况下,您可以简单地执行以下操作:

struct Foo {
void func() const {
bar = const_cast<Foo*>(this);
bar->modify();
}
void modify() { ... }
}

您将在const方法中修改对象,如果调用该方法的Foo实例最初声明为const,这通常是意外的和未定义的行为。但是,由您来获得正确的逻辑。请注意,其他人都希望const的东西const,包括标准库,并且通常(如果不是总是(更好的代码设计是可能的。

在某些情况下它是安全的,即当你有一个非常量Foo对象时。但是,如果您有const Foo对象,则不允许对其进行修改,并且编译器不会因为强制转换而捕获该错误。所以使用它不是一个好主意。

请注意,在您的示例中,Foo是一个临时的,它会在下一行main()中被销毁。

相关文章: