在谷歌上做网站广告要多少钱,北京外语网站开发公司,网站开发的必要性,服务器更改wordpressⅠ. const成员
两种const
我们知道#xff0c;用const修饰 能起到保护#xff0c;使之不被修改的作用。
修饰指针的const有两种位置#xff1a; 我们学过的this指针#xff0c;就被后者所修饰#xff0c;因此无法被修改。 const成员函数
➡️为了保护函数里的成员用const修饰 能起到保护使之不被修改的作用。
修饰指针的const有两种位置 我们学过的this指针就被后者所修饰因此无法被修改。 const成员函数
➡️为了保护函数里的成员使不被修改C引入了const成员函数。 “const成员函数” 就是被const修饰的成员函数。
const的存在使我们不能对任何成员进行修改。 ➡️它长这样
void Date::Print() const
{……
}
这个函数相当于
void Date::Print(const Date* const this)
{……
}
❗注意前后两个const的意义是不一样的。
前者修饰*this保护 this指向的空间的内容 不被修改。
后者修饰this保护this指针不被修改。 ❓这个const的位置好怪啊为啥要放在最末尾而不是开头 const爷就长得怪咋地 不能放开头啊那样const就成修饰返回值的了。 ➡️对比this指针的类型 普通函数类型* const const成员函数const 类型* const ➡️权限问题
就像公司上下级关系权限大的可以调用权限小的
而权限小的不可以调用权限大的。 解释这张图 被const修饰的Print() / d2因为被限制了内容不能修改所以权限相对更低。 未被const修饰的Print() / d1可被修改自由度更高权限相对更高。 彼此的关系就用上下级、平级的关系来理解。 所以const成员函数内部 不可调用 其他非const成员函数
而非const……可调用……const……。 ➡️什么时候加const 如果一个函数不用修改性质是只读的那就加上const来保护。 如果其性质是可读可写那就不能加。 Ⅱ. 取地址运算符重载
先亮身份类的六大默认成员函数之一。
函数名operator
作用自定义类型的取地址 引入
来看这个例子。我们知道自定义类型的运算 需要我们自己去实现 运算符重载运算符同样如此。
而这里我们没写operator那究竟能否取地址成功呢
class Date {
public:Date(int year 1900, int month 1, int day 1) {_year year;_month month;_day day;}
private:int _year;int _month;int _day;
};
int main() {
Date d1(2000, 1, 1);cout d1 endl; //前面没写operator//能否取地址成功呢return 0;
}
结果 取地址成功
❓But why
这是因为C很贴心地将 取地址运算符重载 纳入默认成员函数。
也就是说operator 和前几位默认成员函数的福利一样
如果我们写了编译器会自动调用
如果没写编译器会自动生成并自动调用。 ❓取地址运算符重载长啥样
Here comes the model
Date* operator()
{return this;
} 取地址运算符重载分两种 1. 普通对象 2. const修饰的对象 普通对象取地址
很easy不详讲了。我们来手动实现一下
class Date {
public:Date(int year 1900, int month 1, int day 1) {_year year;_month month;_day day;}
Date* operator() {return this; //this就是它的地址}
private:int _year;int _month;int _day;
};
int main() {Date d1(2000, 1, 1);cout d1 endl;
return 0;
} const对象取地址
当对象被const修饰时会特殊一些。
来看d1和d2的对比
class Date {
public:Date(int year 1900, int month 1, int day 1) {_year year;_month month;_day day;}void Print(){printf(%d-%d-%d\n, this-_year, this-_month, this-_day);}
private:int _year;int _month;int _day;
};
int main() {Date d1(2000, 1, 1); //普通对象d1d1.Print();
const Date d2(2077,1,1); //被const修饰的对象d2d2.Print();
return 0;
} 然而压根编译不过去 普通对象d1没问题而const修饰的d2却亮红牌了为啥
其实const成员报错的原因往往是……权限的放大
来分析下 Print函数中this指针的类型是Date* const 而d2的类型是const Date* const 所以说d2去调用Print()是一次权限的放大是以下犯上大逆不道 对此解决方案是
const修饰的对象应调用const取地址运算符重载
即d2应调用
void Print() const{printf(%d-%d-%d\n, this-_year, this-_month, this-_day);
} 什么时候要手动实现operator ?
我们尽可放宽心即使是const对象编译器仍会自动生成 相应的const operator。
所以无论是 普通对象 还是 const对象 取地址我们都无需手动实现operator。 大部分情况下取地址运算符重载都不用自己写编译器默认生成的就够用了。
只有特殊情况才需要重载
如你不希望别人取到你的地址。那这时就
Date* operator(){return nullptr;
}