查看以下代码:
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
时我非常谨慎,但在这种情况下,它似乎对我来说是合法的。
答案 0 :(得分:4)
不,这有潜在危险。
func()
标记为const
,这意味着它可以被const对象调用:
const Foo foo;
foo.func();
因为this
是const Foo*
。
如果您const_cast
离开const
,最终会得到Foo*
到const
个对象。这意味着通过非const指针(或通过该指针的任何副本,在这种情况下为bar
)对该对象的任何修改都将获得未定义的行为,因为您不允许修改const
对象(duh)。
另外一个显而易见的问题是,你对Foo
班的消费者撒谎说func()
在你做相反的事情时不会修改任何东西。
const_cast
几乎永远不会正确,这对我来说似乎是一个XY问题。
答案 1 :(得分:1)
如果通过&#34; safe&#34;你的意思是&#34;不是未定义的行为&#34;那么是的,这是安全的。 bar
的值将指向您期望的创建对象。
但是,通常不建议使用const_cast
,因为它违反了const
事物不会更改的约定,并且很容易产生未定义的行为(请参阅this comment below)。在这种情况下,您可以简单地执行:
struct Foo {
void func() const {
bar = const_cast<Foo*>(this);
bar->modify();
}
void modify() { ... }
}
您将在const
方法中修改对象,如果调用该方法的Foo
实例最初声明为{{1},则该方法通常会出现意外且未定义的行为}。但是,由您来决定逻辑是正确的。请注意,其他人都希望const
内容为const
,包括标准库,并且通常(如果不总是)可以实现更好的代码设计。
答案 2 :(得分:0)
在某些情况下,它是安全的,即当你有一个非const Foo
对象时。但是,如果您有一个const Foo
对象,则不允许对其进行修改,并且编译器不会因为强制转换而捕获该错误。所以使用它不是一个好主意。
请注意,在您的示例中,Foo
是一个临时文件,会在下一行main()
上被销毁。