const用处:
- 修饰普通变量(和宏常量对比)
- 修饰类成员(修饰成员函数和成员变量)
- 修饰对象
const不能修饰构造函数,拷贝构造函数,析构函数,运算符重载;
因为它们函数本身就要对成员变量进行操作
1.修饰成员变量:
- 一旦成员变量被const修饰,必须要在构造函数初始化列表的位置初始化;
- 也就是说如果类中有const成员变量该类必须显式提供构造函数(见初始化列表)
2.修饰成员函数:
修饰成员函数是修饰三处
const int test (const int a) const
- const修饰函数返回值:在接收时不能修改返回值
- const修饰函数参数:不能修改函数形参
- const修饰成员函数本身:本质是在修饰this指向的值
所以不能修饰全局函数,全局函数中无this指针
const修饰成员函数本身:
- this指针的类型是 类类型* const;
const修饰后类型变成:const 类类型* const;- 经const修饰后不能通过this修改对象中成员变量的值,也就是只能在该函数中读取不能修改,
- 如果要在const函数中修改某个成员变量的值,则需要在定义成员变量前加关键字mutable
void test()//普通成员函数
{
_day+=1;//正确
}
void test()const//const成员函数
{
_day+=1;//错误
}
/*对编译器而言实质是这样的:
void test(const Date*this)
{
const this->_day+=1;//错误
}*/
注: const只能修饰成员函数,不能修饰普通函数,因为普通函数没有this指针,而const实质是修饰this指针;
成员函数是可以调用成员函数的
一般调用是通过指针或者对象调用,而在成员函数中调用,编译器会传一个默认的this指针
this->被调函数
3.修饰对象:
1.const对象(表明该对象中的成员变量不能被修改):
不能调用普通成员函数(普通函数可会修改变量值),只能调用const函数,该函数返回值最好也用const修饰;
普通对象均可调用两种函数
2.const成员函数:
可以调用const成员函数,不能调用普通成员函数(内部可能会修改this指向);
普通成员函数均可调用两种函数
也就是说,普通类型调用范围更大
static
静态全局变量
- 只能初始化一次,未初始化值为0,
- 全局变量作用域是整个工程
- 静态变量作用域是该文件,其它文件不可见
1.修饰成员变量:
- 所有对象都会共享同一份数据,A对象修改了这个数,B对象访问到的值是A修改后的
- 在编译阶段分配内存(程序未运行前就分配了)
- 类内声明,类外初始化
静态的成员变量一定要在类外进行初始化
静态成员变量的特点:
- 该成员变量不属于某个具体的对象,是类的属性,所有对象共享
- 不存储在对象中,也就不会影响sizeof的结果;
- 静态成员变量在类中只是声明,必须在类外初始化
- 不能在初始化列表处初始化;
- 访问方式:
类名::静态成员变量
对象.静态成员变量
针对上述权限问题,如何解决私有静态成员变量无法在类外访问的问题?
答:通过公有函数访问私有的静态成员变量:将此函数放入类中,设置成公有权限;
2.修饰成员函数
所有对象共享一个函数
静态成员函数只能访问静态成员变量
通过(对象.)和(类名::函数名)方式调用,
通过类域调用静态成员函数
也可以不用这样调用,因为其不是对象中的内容,该函数参数就没有隐藏的this指针,所以:
- 不能访问普通成员变量,只能访问静态成员变量;
普通成员变量是属于某个对象的,静态成员函数和对象无关- 不能直接调用非静态成员函数----因为非静态承运函数有一个隐藏的this指针,调用了该指针无法传递;
- 只能调用类中静态成员函数
静态成员函数的调用约定和普通函数一样_cdecl;
static不能修饰构造函数,拷贝构造函数,赋值运算符重载函数,虚函数