首页 文章

修改常量对象

提问于
浏览
6

我正在通过面试问题向初级C开发人员的职位进行调查 . 问题是(引用):

以下代码是否正确?

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

我会回答:

代码本身根据C 03和C 11标准有效,并将成功编译 . 但它可能在赋值指针 - > 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;
}

我的回答是正确的还是我错过了什么?谢谢 .

3 回答

  • 5

    我首先会问他们对"correct"的模糊定义是什么意思 . 您需要知道程序的规范及其 intended behaviour .

    正如你所说,如果他们只是询问它是否编译,那么答案是“是” . 但是,如果他们认为安全做得正确,那么您可以讨论您在问题中陈述的事实 .

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

  • 1

    这段代码可能在法律上是正确的,但我想,问题的目的是确定你是否理解const本身的概念 . 因为,在语义层面上,你有一个函数采用一个隐式的const对象指针,然后它会被修改,这几乎肯定是一个错误 .

    在某些情况下,可能需要这样做(因为修改是一些返回值的缓存,或类似的操作,不会改变对象的语义值),您可以使用 mutable 关键字来处理相关变量 .

  • 0

    作弊的编纂者会承担后果 .

    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;
    }
    

    程序将破解“const Foo&tmp = ite-> first;”

相关问题