我理解编译器认为函数是常量(按位常量),如果任何语句在对象状态中带来修改,那么编译器会抛出错误,如例1所示。
示例1:
class Test
{
public:
int arr[5];
void change(int j) const
{
arr[3]=j;
}
};
int main()
{
Test *ptr=new Test;
ptr->change(3);
}
示例2:
现在我已经将arr
声明为数组指针,但以下似乎已经在一些编译器上工作了 - 但是在我的情况下却没有。这是否意味着它有UB?我遇到的一个合理解释是我们没有直接改变对象,因此这是允许的。如果是这样,为什么UB在我的情况下呢?我正在使用VS2008。
class Test
{
public:
int *arr; //arr is an array
int i;
void change(int j) const
{
arr[3]=j;
}
};
int main()
{
Test *ptr=new Test;
ptr->change(3);
}
答案 0 :(得分:2)
首先,int *ptr
未将ptr
声明为数组。 ptr
此处是 指针 。
其次,您的代码显示未定义行为的原因是您使用的是未初始化的指针。
ptr->change(3)
有效地ptr->arr[3] = 3;
。但你不知道ptr->arr
指向的是什么,所以你不知道你在哪里写3号。也许它会指向一些可以安全覆盖的未使用的内存,也许它会指向未分配的内存并在您尝试访问它时立即崩溃程序,或者它可能会覆盖重要的内容。
另外:编译的原因是虽然arr
是类Test
的一部分,但*arr
却不是。从change
内部,您无法更改arr
,但您可以更改*arr
。