1)const修饰成员变量:成员常量不能被修改初始化:
方法一:只能在构造函数的初始化列表中赋值----比较常用
class A
{
private:
const int n; //成员常量不能被修改
public:
A(int x): n(x) //只能在初始化列表中赋值
{ } ;
}
方法二:把变量static 和 const 并用,在外部初始化
class A
{
public:
A()
{}
private:
static const int i; //注意必须是静态的!
};
const int A::i=3;
注意:为什么const成员不能在构造函数体中进行初始化?
原因:在构造函数中那叫赋值,因为定义在类中已经定义好了,之后只需要在构造函数赋值就可以了,这是定义和赋值时分开的。但是,const变量是必须在定义的时候初始
的,因此只能使用初始化列表中进行,表示是在定义时就能初始化。
2)const修饰成员函数:常函数,函数体为常量,不能改变其他非const成员的值
使用时间:任何不会修改数据成员(即函数中的变量)的函数都应该声明为const 类型
const位置:一般写在函数的尾部来const修饰的成员函数
主要作用:只能被const类对象、指针、引用调用
class A
{
void function()const; //常成员函数, 它不改变对象的成员变量. 也不能调用类中任何非const成员函数。
}
说明:
注意一:在const成员函数内部不允许修改数据成员。反过来,将修改数据成员的成员函数声明为const将导致编译错误。
注意二:const成员函数不允许调用非const成员函数,而只能使用const成员。
非const成员函数可以调用const成员函数。
注意三:可以对const成员函数进行非const版本的重载。
注意四:构造函数和析构函数不允许声明为const类型。构造函数既可以初始化const对象,也可以初始化非const对象。析构函数同理。
注意五:建议将不修改数据成员的成员函数都声明为const。当编写这种成员函数时,若不经意修改了数据成员,编译器将产生错误信息。
代码:
const重载
#include<iostream>
using namespace std;
class A
{
private:
int a;
const int b;
public:
A(int i,int j):b(j)
{
a=i;
}
void print()
{
cout<<"非const函数"<<endl;
cout<<a<<b<<endl;
}
void print ()const
{
cout<<"const函数"<<endl;
cout<<a<<b<<endl;
}
};
void main()
{
A a(1,2);
a.print(); //a为普通的对象,会调用普通的成员函数
const A aa(3,4);
aa.print();//aa为常对象,会调用常成员函数
system("pause");
}
注意四:同一成员函数名,若只有const型,则非const对象可以调用该成员函数,即调用const成员函数。 <见上面的例子const重载>
注意五:同一成员函数名,若既有非const型,又有const型(重载),则非const对象只调用非const成员函数。<见上面的例子const重载>
常对象和常成员函数的调用
#include<iostream>
using namespace std;
class A
{
private:
int a;
const int b;
public:
A(int i,int j):b(j)
{
a=i;
}
void print ()const
{
// a=10;//错误,常函数中不能更新数据成员
cout<<"const函数"<<endl;
cout<<a<<b<<endl;
}
void set(int i,int j)
{
a=i;
// b=j;//错误,const成员不能改变
}
};
void main()
{
const A a(3,4);
// a.set(5,6);//错误,常对象不能调用非常成员,常成员函数是常对象唯一对外出口
a.print(); //正确,常对象只能调用常函数。
system("pause");
}
3)const修饰类对象、对象指针、对象引用:常量对象(对象指针和对象引用),任何成员都不能被修改,只能调用常成员函数。
注意一:const对象在定义后,其值不可被改变。
注意二:const对象不允许进行成员函数的调用,即使是不修改对象的成员函数也不行。除非成员函数本身也声明为const。
即:const对象只可调用const成员函数,不能调用任何非const成员函数(构造与析构函数除外)。
原因:任何非const成员函数会有修改成员变量的企图。
注意三:非const对象既可调用const成员函数,可调用非const成员函数。
注意四:同一成员函数名,若只有const型,则非const对象可以调用该成员函数,即调用const成员函数。 <见上面的例子const重载>
注意五:同一成员函数名,若既有非const型,又有const型(重载),则非const对象只调用非const成员函数。<见上面的例子const重载>
class A
{
void func1();
void func2() const;
}
const A aObj;
aObj.func1(); //错误,常函数只能调用常成员函数
aObj.func2(); 正确
const A* aObj = new A();
aObj-> func1();//错误,常指针只能调用常成员函数
aObj-> func2(); 正确
注意:
1、const对象只能访问const成员函数, 非const对象可以访问任意的成员函数=const成员函数+非const成员函数.
2、const对象的成员是不可修改的,然而const对象通过指针维护的对象却是可以修改的.
3、常量指针被转化成非常量指针,并且仍然指向原来的对象;
常量引用被转换成非常量引用,并且仍然指向原来的对象;
常量对象被转换成非常量对象
4、将Const类型转化为非Const类型的方法 :略
const使用建议:
1、在参数中使用const应该使用引用或指针,而不是一般的对象实例;
2、const在成员函数中的三种用法(参数、返回值、函数)要很好的使用
1)参数:const A& a:只要函数体内是只读,不会修改参数,又想提高效率,则常常使用const &
2)返回值:不要轻易的将函数的返回值类型定为const,除了重载操作符外一般不要将返回值类型定为对某个对象的const引用;
3)常函数:任何不会修改数据成员的函数都应该声明为const 类型。