1.const成员
将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。
我们来看看下面的代码:
·class Date { public: Date(int year, int month, int day) { _year = year; _month = month; _day = day; } void Print() { cout << "Print()" << endl; cout << "year:" << _year << endl; cout << "month:" << _month << endl; cout << "day:" << _day << endl << endl; } void Print() const { cout << "Print()const" << endl; cout << "year:" << _year << endl; cout << "month:" << _month << endl; cout << "day:" << _day << endl << endl; } private: int _year; // 年 int _month; // 月 int _day; // 日 }; void Test() { Date d1(2022, 1, 13); d1.Print(); const Date d2(2022, 1, 13); d2.Print(); } int main() { Test(); }
请思考下面的几个问题:
1. const对象可以调用非const成员函数吗?class Date { public: Date(int year, int month, int day) { _year = year; _month = month; _day = day; } void Print() { cout << "Print()" << endl; cout << "year:" << _year << endl; cout << "month:" << _month << endl; cout << "day:" << _day << endl << endl; } private: int _year; // 年 int _month; // 月 int _day; // 日 }; void Test() { const Date d1(2022, 1, 13); d1.Print(); } int main() { Test(); }
显然是不可以的,(&d1 类型为const Date* 而 this 是 Date*,此操作放大了d1的权限,所以编译器是不支持的)。
2. 非const对象可以调用const成员函数吗?class Date { public: Date(int year, int month, int day) { _year = year; _month = month; _day = day; } void Print() const { cout << "Print()" << endl; cout << "year:" << _year << endl; cout << "month:" << _month << endl; cout << "day:" << _day << endl << endl; } private: int _year; // 年 int _month; // 月 int _day; // 日 }; void Test() { Date d1(2022, 1, 13); d1.Print(); }
运行成功,因为非从const对象的权限是要大于const成员函数的,所以是可以调用的)。
3. const成员函数内可以调用其它的非const成员函数吗?
我们重载了<和>=两个操作符,,>=操作符设置权限为const,我们可以看到编译器同样是不支持,这种操作也是对权限的放大。
4. 非const成员函数内可以调用其它的const成员函数吗?
对比3,这种操作显然是支持的,这是权限的缩小。
成员函数,如果是一个对成员变量只进行读访问的函数->建议加const,这样const对象和非const对象都可以使用。
成员函数,如果是一个对成员变量要进行读写访问的函数-> 不能加const,否则不能修改成员变量。
2. 取地址及const取地址操作符重载
这两个默认成员函数一般不用重新定义 ,编译器默认会生成。
class Date { public: Date* operator&() { return nullptr; } const Date* operator&()const { return this; } private: int _year; // 年 int _month; // 月 int _day; // 日 };
这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如想让别人获取到指定的内容!
比如我们让非const对象得到空地址:class Date { public: Date(int year = 1, int month = 1, int day = 1) { } Date* operator&() { return nullptr; } const Date* operator&()const { return this; } private: int _year; // 年 int _month; // 月 int _day; // 日 }; int main() { Date d1; const Date d2; cout << &d1 << endl; cout << &d2 << endl; }