const用法(转)

/-----以下引用自网络---------

1.常量不能为左值

cannot convert 'this' pointer from 'const class X' to 'class X &'
例子:
#include <iostream.h>
class X
{
   int i;
   public:
     void modify() {cout<<"haha"<<endl;}
};


const class X fun(){return X();}
void main()
{
 //fun().modify(); //常量不能为左值,所以下例也不成立:
 //error C2662: 'modify' : cannot convert 'this' pointer from 'const class X' to 'class X &'
 const X g = X();
 g.modify();
}
解决方案
void modify() const  {cout<<"haha"<<endl;}

2. 类常量成员初始化 (用初始化成员列表)

class Y{
public:
    const size;
        Y();
};
Y::Y():size(100){}
class X{
        enum{i=100};
};
2 .    c语言中去除const修饰
a.     能否将一个非常量对象的地址赋给一个常量指针?
b.     能否将一个常量对象的地址赋给一个非常量指针?若确要如此,该如何做?
可以将非常量对象地址赋值给常量指针,但是不能将常量对象地址给非常量指针,因为其无法保证不修改常量对象。
若却要如此,则只能强制转换,能编译通过,但却可能存在隐患。因此编译器的工作就是将一切可能的隐患扼杀在摇篮中。

void main()
{
        const int i=5;
        int *j=const_cast<int *>(&i);
}

3,,const内存分配

常量有没有存储空间,或者只是编译时的符号而已?
不一定。
在C中,define常量是预处理阶段的工作,其不占据内存。但是const常量总是占据内存
在C++中,const常量是否占据存储空间取决于是否有引用该常量地址的代码。C++对于const默认为内部链接,因此const常量定义通常都放在头文件中,即使分配内存也不会出现链接错误。
若不引用常量对应的地址,则不会为其分配空间。

Const是用来替换define的,因此其必须能够放在头文件中,在C++中const变量是默认为内部链接的,即在其他文件中看不到本文件定义的const变量,因此链接不会出现问题。Const变量在定义的时候必须初始化,除非显式的指定其为extern的。通常C++中会尽量避免为const变量分配内存storage的,而是在编译阶段将其保存在符号表symbol table中。当用extern修饰const变量或引用其地址时,将强制为其分配内存,因为extern表示采用外部链接,因此其必须有某个地址保存其值。
#include <iostream.h>
const int i=100;   //无法找到i的符号,因为没有为其分配存储空间。
const int j=i+100;   //强迫编译器为常量分配存储空间
long address=(long)&j;
char buf[j+10];
int main(int argc, char* argv[])
{
 const char c=cin.get();
 const char d=3;  // 局部变量栈区
 char test1[d+10];
 //char test2[c+10];  error const char c必须到运行时刻动态获取其初值。char test2[c+10]编译无法通过,因为无法确定c就无法确定数组长度。
 const char c2=c-'a'+'A';
 cout<<c<<" "<<c2<<endl;
 return 0;
}
五只猴子摘了一堆桃子,可是怎么也平分不了。于是一致同意先去睡觉,明天再分。夜里,一只猴子偷偷起来,先吃掉一个桃子,剩下的桃子正好平分成5份。它蒇起自己的1份,然后再去睡觉。过了一会,第二只猴子起来,也吃掉1个桃子,剩下的桃子也正好平分成5份。它也藏起了自己的1份,然后再去睡觉。第三只、第四只和第五只也都依次这样做。问最初那堆桃子至少有多少个?
第五只猴子吃掉一个桃子后剩5a个 
第四只猴子吃掉一个桃子后剩5(5a+1)/4=25a/4+5/4 
第三只猴子吃掉一个桃子后剩5(25a/4+5/4+1)/4=125a/16+45/16 
第二只猴子吃掉一个桃子后剩5(125a/16+45/16+1)/4=625a/64+305/64 
第一只猴子吃掉一个桃子后剩5(625a/64+305/64+1)/4=3125a/256+1845/256 
原来共有桃子3125a/256+1845/256+1=3125a/256+2101/256=(12a+8)+53(a+1)/256
桃子数是整数 所以a=255 桃子总数3121个 

第一只猴子吃掉一个剩3120 拿走6242496 
第二只猴子吃掉一个剩2495 拿走4991996 
第三只猴子吃掉一个剩1995 拿走3991596 
第四只猴子吃掉一个剩1595 拿走3191276 
第五只猴子吃掉一个剩1275 拿走2551020a255+256n(n为自然数)时 对应无数组解 上面的是最小正整数解

const类型定义:指明变量或对象的值是不能被更新,引入目的是为了取代预编译指令

****常量必须被初始化***************

const的作用

1)可以定义const常量         例如:
             const int Max=100;
             int Array[Max];        
   (2)便于进行类型检查            例如:
             void f(const int i) { .........}
        编译器就会知道i是一个常量,不允许修改;
   (3)可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。
        还是上面的例子,如果在函数体内修改了i,编译器就会报错;
        例如: 
             void f(const int i) { i=10;//error! }
    (5) 为函数重载提供了一个参考。
         class A
         {
           ......
           void f(int i)       {......} file://一个函数
           void f(int i) const {......} file://上一个函数的重载
            ......
          };
     (6) 可以节省空间,避免不必要的内存分配。
         例如:
              #define PI 3.14159         file://常量宏
              const doulbe  Pi=3.14159;  file://此时并未将Pi放入ROM中
              ......
              double i=Pi;               file://此时为Pi分配内存,以后不再分配!
              double I=PI;               file://编译期间进行宏替换,分配内存
              double j=Pi;               file://没有内存分配
              double J=PI;               file://再进行宏替换,又一次分配内存!
         const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝。7) 提高了效率。
           编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。

使用const

1)修饰一般常量,常数组,常对象
   修饰符const可以用在类型说明符前,也可以用在类型说明符后。      例如:   
           int const x=2;  或  const int x=2;

       int const a[5]={1, 2, 3, 4, 5};    或  const int a[5]={1, 2, 3, 4, 5};

           class A;      const A a;  或     A const a;
     
   (2)修饰指针
        const int *A;   或  int const *A; //const修饰指向的对象,A可变,A指向的对象不可变
        int *const A;              //const修饰指针A,     A不可变,A指向的对象可变 
        const int *const A;      //指针A和A指向的对象都不可变3)修饰引用
        const double & v;      该引用所引用的对象不能被更新
 (4)修饰函数的返回值:
        const修饰符也可以修饰函数的返回值,是返回值不可被改变,格式如下:
            const int Fun1(); 
            const MyClass Fun2();
   (5)修饰类的成员函数:
        const修饰符也可以修饰类的成员函数,格式如下:
            class ClassName 
            {
             public:
                  int Fun() const;
                    .....
             };
        这样,在调用函数Fun时就不能修改类里面的数据 
    (6)在另一连接文件中引用const常量
         extern const int i;     //正确的引用
         extern const int j=10;  //错误!常量不可以被再次赋值

*********放在类内部的常量有什么限制?

      class A
        {
         private:
           const int c3 = 7;               // err
           static int c4 = 7;               // err
           static const float c5 = 7;  // err
          ......
  };
 初始化类内部的常量
        1 初始化列表:
         class A
         {
          public:
                A(int i=0):test(i) {}
          private:
                const int i;
          };
         2 外部初始化,例如:
         class A
         {
          public:
                A() {}
          private:
                static const int i;  
          };
          const int A::i=3; 


题目:
const int a; int const a;//想同,表示a的值不可变。
int *const b=a; //表示指针b的值不可变。但指向对象的值[*b]可变。
const int *const b=a; int const *const b=a;//想同,表示指针b的值不可变。且指向对象的值[*b]也不可变。

“`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值