复习:
1、
2、重点:
不能重载的
3、赋值运算符重载
4、
5、为什么要有返回值
return *this,可以不要
为了遵从基本类的赋值,为了支持连续赋值
6、
7.
重载:函数名
运算符重载(重载符号):==替换成operator==
8、
1、深入探索构造函数
初始化的两种方式:
(1)在函数体内初始化
class Date
{
public:
Date(int year = 2016, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
(2)初始化列表
class Date
{
public:
Date(int year , int month , int day )
:_year = year,
_month = month,
_day = day
{
;
}
private:
int _year;
int _month;
int _day;
};
为什么有了第一种还要第二种来初始化?
答:因为高效
(3)
2、拷贝构造的次数
两种初始化的方法可以结合起来使用
public:
Date(int year , int month , int day )
:_year = year,
_month = month
{
;_day = day;
}
不用参数列表初始化初始化也会初始化为随机值
所以建议用列表初始化
3、必须在表中初始化
(1)常量成员变量
(2)引用
(3)没有缺省构造函数的类成员变量。
没有写缺省构造函数,系统无法使用
解决方法:
a)加缺省
2)用列表初始化(._t(hour))
4、成员变量按声明顺序依次初始化,而非初始化列表出现的顺序
class Date
{
public:
Date(int x)
: _day(x)
, _month(_day)//随机值(不管列表中出现的顺序,都按照声明的顺序)
, _year(x)
{
cout << "Date ()" << endl;
}
void Display()
{
cout << "year:" << _year << endl;
cout << "month:" << _month << endl;
cout << "day:" << _day << endl;
}
private:
int _year; // 年
int _month; // 月
int _day; // 日
}
所以习惯上下保持一致
下一个开始:
类和对象--const&内联&静态成员&友元
1、const修饰的成员函数
附:
(1)在成员函数后面加const,const修饰this指针所指向的对象,也就是保证调用这个const成员函数的对象在函数内不会被改变
(2)调用成员函数的对象不能改变
(3)const函数,非const和const都可以调用
(4)SetDate()无const说法
思考:
(1)const对象可以调用非const成员函数和const成员函数吗?
(2)非const对象可以调用非const成员函数和const成员函数吗?
(3)const成员函数内可以调用其它的const成员函数非const成员函数吗?
(4)非const成员函数内可以调用其它的const成员函数非const成员函数吗?
2、取地址运算符重载(这两个默认成员函数一般不用重新定义)
Date* operator&()
{
return this;
}//系统生成默认的
cout<<&d<<endl;//--->const Date* operator&()const
3、inline(内联)
(1)以inline修饰的函数叫做内联函数,编译时C++编译器会调用内联函数的地方展开,没有
函数压栈的开销,内联函函数提升程序运行的效率
特点:
(1)inline是一种以空间换时间的做法,省去调用函数额开销。所以代码很长或者有循环/递归的的函数不适宜使用内联。
(2)inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归等等,编译器优化时会忽略掉内联。
(3)inline必须函数定义放在一起,才能成为内联函数,仅将inline放在声明前是不起不作用的。(4)定义在类内的成员函数默认定义为内联函数。
思考:
C++建议以const/枚举/内联去替代宏,为什么?
1、都可以定义常量const,enum,#define
但是#define无类型安全性检查,而其他的有
2、#define不可以调试,后面的两种可以调试
3.为什么内联
#define出了可以定义宏常量,
宏函数(相当于inline,但是inline如果错误的话,编译不通过)
(1)#define,无法调试,inline可以调试(一样高效,但是可以调试)
(2)#define,容易出错,例如:ret=ADD(a,b)*c//a+b*c,inline如果错误的话,编译不通过
考点:c和c++的差异
4、友元
作业:实现万年历
构造函数
Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
年月日有可能非法
解决方法:
(1)添加断言
assert(year>=1900&&_month>0&&_month<13&&_day>0&&_day<=_GetMonthDay(year,day))
(2)_GetMonthDay函数
int GetMonthDay(int year, int month)
{
int monthArray[13] = {0, 31, 28, 31, 30};
int day = monthArray[month];
if (month == 2 && IsLeapYear(year))
{
day += 1;
}
return day;
}
(3)构造函数中
如果错误,则非法日期定义为初始值
用
if ()//正确
{
;//直接初始化
}
else//错误日期
{
;//初始化为初始日期或则断言assert(flase);
}
(4)加法,日期加天数
Date operator+()//有可能是负数
{
Date tmp(*this);
if (day < 0)
return *this-> - (-day));
else
{
while (tmp._day>GetMonthday(tmp, _year, tmp._month))
{
tmp._day -= _GetMonthDay(tmp, _year, tmp._month);
if (tmp.month == 12)
{
tmp._year++;
tmp._month = 1;
}
else
{
++tmp.month;
}
}
}
return tmp;
}
转载于:https://blog.51cto.com/10742910/1735656