以上代码运行时是会报错的。
首先“hello world”这是一个常量,是存放在代码段中的。是不可改变的。
因为char *s=“hello world” 这句代码只会将“hello world”在代码段中的地址交给s这个指针。
所以下面的那句s[0]='B', 是通过s这个指针访问代码段中的“hello world”这个常量,因为常量是不可更改的,所以程序会报错。
所以,其实,对于第一句指针s的定义,正确的是在其前面加上一个const关键字,告诉程序,这个常量是不可更改的。
以上程序正确的写法如上。
char s[]="hello world" 这句代码,首先声明的s是一个数组,所以在栈中给s这个数组分配一个很大的空间。
之后的赋值运算符,会将代码段中的“hello world”拷贝到栈中,所以下面的s[0]='B' 不会报错。
由以上的分析可以看出,在程序中通过拷贝传递这个对象,需要在栈中分配内存并进行拷贝,这会花费很大的空间和时间。
所以,我们最好是只传对象的指针,但是这样的话,我们没办法保证程序后面的代码不会对指针指向的对象进行修改,由此,引出了使用const的必要性。
当我们确定不会对某个对象进行修改的时候,最好是将其定义成const,这样可以保证程序在之后都不能修改当前对象。
再一个问题:
当我们在一个类的成员函数的后面加上一个const,则这个函数就变成了常量成员函数。常量成员函数不能改变调用它的对象的内容!【这是因为加上const之后,类的变成了指向常量的常量指针。所以不能改变this指向的内容了】
this指针由Date *const 变成了 const Date *const
进一步:
以上代码可以正确运行,输出的结果为:f() const
上面的两个f() 函数,看起来不能构成重载关系,因为函数重载需要函数的参数列表不同。
但是其实是可以的,因为其实两各f 的参数列表定义如下:
所以在一个函数后面加上const,将函数变成常量成员函数,是可以构成重载的。
另外:
图1
以上这个代码在编译的时候会报错。
需要修改成:
图2
才可以。修改的地方在:需要增加一个A的构造函数,在A的构造函数中给 i 赋初始值。
如果不这样的话,还可以有下面这种方式:
图3
以上这个代码编译的时候是没问题的。
不同点在于前面一个代码是 const A a,这个的代码是A a,没有const !
总结也就是:
类中的const 变量,需要在编译的时候就让编译器知道值到底是多少。如果编译器不知道的话就会报错。这是因为const在后面的程序代码中是确定不能改变的,所以要求在编译的时候值就能确定!!
c++是先编译在运行的
同理,图1 中,虽然A类中的i定义不是const,但是将a定义成了const,所以这种情况下,a在之后的程序中也是不能改变的,所以,也要求在编译的时候就能将a确定下来,所以需要加上i的初始化。
而图3没有初始化i,也没问题,就在于a不是const的,所以并不需要在编译的时候就要明确i到底是等于多少,只需要让编译器明白,在对象a中,有一个i变量存在,具体是多少,我现在并不关心,因为现在不知道,对之后的整个程序也没有影响。