修改常量对象

Modifying constant object

本文关键字:对象 常量 修改      更新时间:2023-10-16

我正在查看一个初级C++开发人员职位的面试问题。问题是(引用):

以下代码是否正确

struct Foo
{
    int i;
    void foo ( void ) const
    {
        Foo* pointer = const_cast<Foo*>(this);
        pointer->i = 0;
    }
};

我会回答:

根据C++03和C++11标准,代码本身是有效的,并且将成功编译。但它可能会在赋值pointer->i期间调用未定义的行为=0如果调用foo()的类的实例被声明为const

我的意思是,以下代码将成功编译并导致未定义的行为。

struct Foo
{
    int i;
    Foo ( void )
    {
    }
    void foo ( void ) const
    {
        Foo* pointer = const_cast<Foo*>(this);
        pointer->i = 0;
    }
};
int main ( void )
{
    Foo foo1;
    foo1.foo();   // Ok
    const Foo foo2;
    foo2.foo();   // UB
    return 0;
}

我的答案是正确的还是遗漏了什么?非常感谢。

我首先会问他们对"正确"的模糊定义是什么意思。您需要了解程序的规范及其预期行为

正如你所说,如果他们只是问它是否编译,那么答案是肯定的。然而,如果他们认为这样做是正确的,那么你可以讨论你在问题中陈述的事实。

通过这样回答,面试者可以看到你是如何分析被问到的问题的,而不是直接回答,在我看来这是一件好事

这段代码在法律上可能是正确的,但我想,问题的目的是确定您是否理解const本身的概念。因为,在语义级别上,您有一个函数采用隐式const对象指针,然后对其进行修改,这几乎可以肯定是一个错误。

在某些情况下,这可能是需要的(因为修改是对返回值的缓存,或者类似的操作不会更改对象的语义值),您会对有问题的变量使用mutable关键字。

作弊同谋将承担后果。

struct Foo
{
    int i;
    Foo(int a):i(a){}
    void foo ( void ) const
    {
        Foo* pointer = const_cast<Foo*>(this);
        pointer->i = 0;
    }
    bool operator<(const Foo& rhs) const{
        return i<rhs.i;
    }
};
#include <map>
int main ( void )
{
    std::map<Foo,int> kk;
    for(int i=0;i<10;++i){
        kk.insert(std::make_pair(Foo(i),i));
    }
    std::map<Foo,int>::iterator ite = kk.find(Foo(4));
    const Foo& foo4 = ite->first;
    foo4.foo();
    ite = kk.find(Foo(4));
    const Foo& tmp = ite->first; // crack
    return 0;
}

程序将首先在"constFoo&tmp=ite->first;"

处破解