const的普通用法及其在对象中的使用

来源:互联网 发布:离坚白 知乎 编辑:程序博客网 时间:2024/05/29 10:41

const的普通用法
在C++中,常数在编译时是放在代码段的,所以与其他的变量不同,常数是要在编译器做编译时就要知道值的。比如说:

 const  int bufsize;//这是错误的写法。

因为在编译时编译器不知道其值,所以正确的写法是在声明时就要赋值。
如果在其他的文件中含有一个叫做bufsize的变量,那么在当前的文件中做了这样的事情:

extern const int bufsize;//这样做是正确的。

原因是,这个extern告诉编译器,bufsize肯定存在于其他的文件中,并且在该文件中将其声明为const的(在其他的文件中是否是const是未知的,只要求在该文件中是const的)。但是在使用时,也要求bufsize是一个已知的常数。
在有的写法中,比如:char *s="hello,world!",该写法实际上等价于const char *s="hello,world!",所以如下程序中,将会有这样的事情发生:

char *s = "hello,world!";            cout << s << endl;            S[0] = 'B';            cout << s << endl;

在该代码中,当在做编译时是不会出错的,但是会出现警告。原因是此时的s所指的内容被认为是一个常数,在编译时被放在代码段中。当编译时在第一句不知道后面是否将其改变,在第三句代码时也不知道其访问的是否是const的,所以编译会通过,但是会出现警告。但是在运行时,s[0]会内存中找s所指的那一块内存,但是找不到,就会运行崩溃。因为s此时不能去代码段中访问,代码段在此时是被保护起来的。
但是如果将char *s = "hello,world!"改为const char *s = "hello,world!",当再次使用s[0] = ‘B’时就会在编译时报出错误,因为此时已经知道了要访问修改的为const的值。
当改为char s[] = "hello,world!"就会不一样,原因是在这句代码中,s被认为是一个变量,放在内存的堆栈区中,是可访问的,所以能够成功被修改。
实际上,const的数和变量中的数存放的地址相差很大,const的数存在在代码段,与main函数在大概相同的地方,但是堆栈的地址则会大得多。
声明一个const的对象
当你声明一个const的对象时,意味着你在声明该对象的时候就要对其进行初始化工作。原因是const的东西在以后无法改变,所以要在声明的时候就必须进行初始化。
对象中的const成员
const的成员变量,代码如下:

    class A{            const int I;        public:            A:i(0)(){}            ~A(){}            void fun(){ cout << "fun() " << endl;}            void fun()const { cout << "fun const" << endl; }    };    int main(){        const A a;        a.fun();        return 0;    }
在以上的代码中,如果在类A中没有对i的初始化列表,则会编译出错。原因是对于const的东西一旦定义,以后便不能改变,所以必须初始化。运行的结果会是:fun const,为什么呢?为何没有说两个相同的函数名和相同的参数列表重复定义呢?实际上,在类的每一个函数成员变量中,都有这样一个隐藏的参数,即:`A* this`。在这两个同名函数中,实际上参数是不相同的,他们分别为:`fun( A* this )`和`fun( const A* this )`。故而在调用的时候不会出现另一种情况。还有一定点必须说明,const的对象只能调用const的成员函数。