我正在通过面试问题向初级C ++开发人员的位置看。问题是(引用):
以下代码是否正确?
struct Foo
{
int i;
void foo ( void ) const
{
Foo* pointer = const_cast<Foo*>(this);
pointer->i = 0;
}
};
我会回答:
代码本身根据C ++ 03和c ++ 11标准有效,并且将成功编译。 但它可能会在分配指针 - &gt; 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;
}
我的回答是正确的还是我遗失了什么?谢谢。
答案 0 :(得分:5)
我首先会问他们对“正确”的模糊定义是什么意思。您需要了解该计划的规范及其预期行为。
正如你所说,如果他们只是在询问它是否编译,那么答案就是'是'。但是,如果他们认为做得安全是正确的,那么您可以讨论您在问题中陈述的事实。
通过回答这种方式,面试的人可以看到你是如何分析你被问到的,而不是直接回答,这在我看来是一件好事。
答案 1 :(得分:1)
这段代码可能在法律上是正确的,但我想,问题的目的是确定你是否理解const本身的概念。因为,在语义层面上,你有一个带有隐式const对象指针的函数,然后它会被修改,这几乎肯定是一个bug。
有些情况下,可能需要这样做(因为修改是一些返回值的缓存,或类似的操作,不会改变对象的语义值),您可以使用mutable
关键字有问题的变量。
答案 2 :(得分: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&amp; amp = ite-&gt; first;”