2016-01-13 84 views
0

我明白,一个功能被认为由编译器是恒定的(二进制位常量性),并且如果任何陈述的对象的状态带来修改然后编译器会引发错误如实施例1中编译器如何处理const函数?

实施例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); 
} 
+3

int \ * arr; // arr是***不是***数组 – immibis

+0

而在给出的代码中,它不仅仅是一个数组,它甚至不是一个可用的指针;我相信它最终会默认初始化为'nullptr'(甚至可以算作POD类型,内存不初始化?)。所以它肯定是坏的。 – ShadowRanger

+0

@ ShadowRanger它将被初始化。 – immibis

回答

2

首先,int *ptr不声明ptr为一个数组。 ptr指针这里。

其次,您的代码展示未定义行为的原因是您使用的是未初始化的指针。

ptr->change(3)有效确实ptr->arr[3] = 3;。但你不知道什么ptr->arr指向,所以你不知道你在写3号的地方。也许它会指向一些可以覆盖的未使用的内存,也许它会指向未分配的内存,并在您尝试访问它时立即崩溃您的程序,或者它可能会覆盖重要的内容。

 

另外:它编译的原因是,虽然arr是类Test的一部分,*arr不是。从change内部,你不能改变arr,但你可以改变*arr

+1

_它编译的原因是,尽管arr是类Test的一部分,但arr不是。从内部改变,你不能改变arr,但你可以改变* arr_:你的意思是arr指向的地址(incase int * arr)应该保持不变,但是值可以改变?因为arr包含被认为是对象的一部分的某个位置的地址,而指向的内存位置不在对象的范围内。那是对的吗? – anurag86