修改常量对象
Modifying constant object
我正在查看一个初级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;"
相关文章:
- 代理对象的常量正确性
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- 如何使用数据对象上的常量指针初始化类
- 为什么C++在将一个对象复制到另一个对象时需要对这两个对象进行低级常量限定
- 为什么当我们有常量引用时创建临时对象?
- 是否可以使用非常量指针调用非常量函数,以及当两个unique_ptrs指向同一个对象时程序的行为方式?
- C++,如何使用常量对象和非常量对象进行比较?
- 通过从构造函数中的'this'复制的指针改变常量对象
- 为什么我可以改变常量对象中的成员变量,这是返回常量对象函数的结果?
- C++将常量字符* 指针数组传递给对象
- C++ 对非常量对象的常量引用和对非常量对象的非常量引用之间的区别
- 未定义的对象(〔basic.life〕/8):为什么允许引用重新绑定(和常量修改)
- 当类具有常量时,将对象插入到向量中
- 算法不适用于非常量对象的const_iterator
- C++:允许临时对象调用非常量成员函数的设计理念是什么?
- 为什么MSVC14允许声明指向动态未初始化常量对象的指针
- 可作为常量调用的比较对象
- C++中的常量对象或私有/常量数据成员(变量)?
- 将值从指针复制到常量对象参数
- 如何正确组合可变对象常量