const方法中的const_cast'this'将'this'赋值给外部变量?

时间:2017-08-23 10:49:46

标签: c++

查看以下代码:

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时我非常谨慎,但在这种情况下,它似乎对我来说是合法的。

3 个答案:

答案 0 :(得分:4)

不,这有潜在危险。

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

const Foo foo;
foo.func();

因为thisconst 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()上被销毁。