1、const在C++之中有着奇怪的现象。C++中类之外定义的const对象位于全局区,const对象一经定义就必须初始化,初始化的const对象位于全局区的初始化区域,在类之外定义的const对象不能修改。
2、C++类之中定义的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;
}
当然实际工程中的情况要比这写要复杂的多,只有多做多练才能达到熟练应用的境界。