2023_1_2下午17.32,天气微冷,心情还行
这里是目录标题
前言
主要还是对C++特性的一个实践操作使用。算是对C++特性的复习。
关于const的使用
1.建议成员函数中不修改成员变量的成员函数,都可以加上const,这样的话普通对象和const对象都可以调用。
2.假如函数的声明和定义分离,声明和定义都要加上const。
const对象不可以调用非const成员函数
权限放大
非const对象不可以调用const成员函数
权限缩小
const成员函数内不可以调用非const成员函数。
原因是const函数内调用其他函数就需要使用this指针来调用,,因为this指针调用的本质还是解引用。*->和(this).等价。
所以还是需要传递const对象。导致权限放大。
非const成员函数内不可以调用const成员函数。
权限缩小。
取地址运算符的重载
取地址是默认成员函数,不需要写编译器自动生成,百分之99不需要我们来写。
这个版本是const对象调用的。
const Date* operator&() const
{
return this;
}
重载流插入<<运算符
对于普通类型,比如int double这些都在ostream的类里面进行了函数重载,已经在库里写好了。
所以我们平时可以直接用。
把对象插入到流 cout 中
友元函数,就是在函数前面加上friend,友元函数是为了可以访问类里面的私有变量。
ostream& operator<<(ostream& out, const Date& d)
{
out << d._year << d._month << d._day;
return out;//支持连续赋值
}
声明和定义最好分离,声明在.h,定义在.cpp,防止.h在多个.cpp多次展开。
重载流提取>>运算符
流提取运算符是istream的对象。
从流cin提取数据到对象中
构造函数的初始化列表
构造函数的作用就是用来初始化。
默认构造函数有三个。
1.不写自动生成的。
2.无参的。
3.全缺省的。
并不是必须提供默认构造函数。
函数体内初始化
Date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
初始化列表
初始化列表的价值是什么?
学了初始化列表后,建议以后写构造函数都在初始化列表里面初始化。
在日期类里的私有成员变量是声明。
用类创建的对象d,d的成员变量什么时候定义?
答案:初始化列表是对象成员定义的地方。
普通变量比如int,double可以不初始化,可以后面赋值在修改。
因为有些成员必须在定义的时候初始化。
比如const int _n; int& ref;这些定义。必须有初值。因为const是常量,后期不能修改。引用只能引用一个实体。
Date(int year = 1, int month = 1, int day = 1)
:_year(year)
,_month(month)
,_day(day)
{
}
explicit关键字
隐士类型的转换是通过生成临时变量来实现的。
explicit这个关键字的作用是不允许隐士类型的转换
注意:只有单参数才支持隐士类型的转换
explicit Date(int year)
{
}
只要在构造函数的前面加上explicit关键字就可以使下面语句报错。
//2022先构造生成临时变量,然后临时变量在进行拷贝构造。
再例如,string创建的对象s1,用字符串hello构造,但是hello只是字符串不是对象,所以正常情况下需要先用hello构造一个对象。但是这里有隐士类型的转换,hello自动构造一个临时对象。然后临时对象具有const常性,再用来构造s1.
Date d2 = 2022;
string s1("hello");
static静态成员
静态成员的作用可以统计某个对象创建了几个。
C++的静态变量是在属于整个类的。注意他是在类里面声明,类外进行定义的。
具体使用方法代码如下。
class Date
{
private:
//类内声明
static int _count1;
static int _count2;
};
//类外定义
int Date::_count1 = 0;
int Date::_count2 = 0;
不仅变量是静态的,函数也可以是静态的。
对于静态函数,也可以使用对象调用,但是不传递this指针,能用对象调用的原因是用来突破类域。
也可以通过类域来调用。
注意:静态函数内不能访问非静态成员,原因就是因为静态函数没有this指针。