C/C++语法高阶:const的应用,const在类中的体现

1、const在C++之中有着奇怪的现象。C++中类之外定义的const对象位于全局区,const对象一经定义就必须初始化,初始化的const对象位于全局区的初始化区域,在类之外定义的const对象不能修改。

2C++类之中定义的const对象分为静态的和非静态的,static const 对象位于全局区,在初始化之后是不能修改的。非static的const对象位于栈区,可以通过指向该对象的指针来修改,但是修改的对象仅限于对象之内(意思是:在其中一个对象修改,在另一个对象中任然保持不变)。

如下所示

 

#include <iostream>
const int NUM = 12;    //类之外定义的全局变量,这个是不能修改的
class MyClass
{
public:
	static int m_static ;              //声明一个静态对象
	static const int  m_const_static;  //声明一个静态的常量
	const int m_const;                 //声明一个常量
public:
	MyClass():m_const(10)
	{

	}
	MyClass(int temp):m_const(temp)
	{

	}

	void Show(void)
	{
	    std::cout<<"today is beautiful"<<std::endl;
	}

private:
protected:
};

const int MyClass::m_const_static = 12;  //静态常量的初始化
int MyClass::m_static = 10;              //静态变量的初始化

int main()
{
	MyClass m1;
	MyClass *pM = new MyClass(10);

     //输出修改前的变量的值,此时m_const_static = 12,m_static=10,
    std::cout<<m1.m_const_static<<" "<<m1.m_static<<" "<<m1.m_const<<std::endl;
     //m_const =10;
    std::cout<<pM->m_const_static<<" "<<pM->m_static<<" "<<pM->m_const<<std::endl;


    int *p_Const = const_cast<int *>(&m1.m_const);
    int *p_Static = &MyClass::m_static;
    int *p_Static_Const = const_cast<int* >(&MyClass::m_const_static);

    *p_Static = 17;  //修改m_Static
    *p_Const = 19;   //修改m1对象的m_Const

    /*m1.m_const_static = 12,m1.m_static = 17,m1.m_const =19;*/
    std::cout<<m1.m_const_static<<" "<<m1.m_static<<" "<<m1.m_const<<std::endl;

   /*pM->m_const_static = 12,pM->m_static = 17,pM->m_const =10;*/
    std::cout<<pM->m_const_static<<" "<<pM->m_static<<" "<<pM->m_const<<std::endl;

    std::cout<<*p_Static_Const<<" "<<*p_Static<<" "<<*p_Const<<std::endl;

    std::cin.get();

    return 0;
}
  这个代码需要解释一下:

  定义两个类对象来做一下对比:

MyClass m1;
MyClass *pM = new MyClass(10);
  经过初始化之后:

m1.m_const_static = 12, m1.m_static=10,m1.m_const = 10
pM->m_const_static = 12,pM->m_static = 10,pM->m_const=10


  然后将指针分别绑定到相关的对象:

int *p_Const = const_cast<int *>(&m1.m_const); //p_Const 绑定到m1,绑定之前要去掉const属性
int *p_Static = &MyClass::m_static;  //p_Static绑定到类的static对象m_static
int *p_Static_Const = const_cast<int* >(&MyClass::m_const_static);//p_Static_Const绑定到类的const static对象m_const_static

*p_Static = 17;  //修改m_Static
*p_Const = 19;   //修改m1对象的m_Const
  然后将修改后的对象进行输出:

/*m1.m_const_static = 12,m1.m_static = 17,m1.m_const =19;*/
std::cout<<m1.m_const_static<<" "<<m1.m_static<<" "<<m1.m_const<<std::endl;

/*pM->m_const_static = 12,pM->m_static = 17,pM->m_const =10;*/
std::cout<<pM->m_const_static<<" "<<pM->m_static<<" "<<pM->m_const<<std::endl;
 我们发现,类之中的 非static const 是可以修改的,但是修改时仅限于某个对象,这里对m1中的const对象进行了修改,最终结果显示只有m1中的m_Const发生了改变,而pM中的对象则没有改变。

 而在修改static对象时,在m1和pM中均有体现。

 下面是程序运行后的结果:

 


3、如果class内部含有const static 整形数据成员,那么根据C++标准规格,我们可以在class之内直接给予初始值。这里的整型泛指所有整数型别,不单是指int


4、const可以对成员函数起到很好的修饰作用。在设计类的时候,如果成员函数内部不会对对象进行修改,那么我们就应该把成员函数设为const。

   const对象只能调用const成员函数,非const对象既可以调用const成员函数,也可以调用非const成员函数。

   const 成员函数的声明:

int GetData() const;
   const 是放在尾部对该函数进行修饰的。上面说的两点可能有些抽象,看一个例子就行了:

#include <iostream>
#include<string.h>

using namespace std;
class testClass
{
private:
    int data;
    char sz[12];
public:
    testClass():data(24)
    {
       strcpy(sz,"beautiful");
    }

    void display() const
    {
        cout<<"const display:"<<endl;
        cout<<data<<" "<<sz<<endl;
    }

    void display()
    {
        cout<<"non const display:"<<endl;
        cout<<data<<" "<<sz<<endl;
    }

    friend ostream& operator<<(ostream &out,const testClass& m_ts)
    {
        m_ts.display();
        return out;
    }

    friend ostream& operator<<(ostream &out,testClass& m_ts)
    {
        m_ts.display();
        return out;
    }

};

int main()
{
    testClass m_test;
    const testClass m_const_test;
    cout<<"m_test:"<<endl;
    cout<<m_test;

    cout<<"m_const_test:"<<endl;
    cout<<m_const_test;
    return 0;
}

程序运行的结果如下所示:


可以看到 非const的m_test重载的是

 void display()
    {
        cout<<"non const display:"<<endl;
        cout<<data<<" "<<sz<<endl;
    }
而 const 的m_const_test重载的是:

void display() const
    {
        cout<<"const display:"<<endl;
        cout<<data<<" "<<sz<<endl;
    }

当然实际工程中的情况要比这写要复杂的多,只有多做多练才能达到熟练应用的境界。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值