const成员函数 :在成员函数后面加const,const修饰this指针所指向的对象,也就是保证调用这个const成员函数的对象在函数内不会被改变。
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
:_year(year)
, _month(month)
, _day(day)
{}
void Show1() const //const Date* this
{
cout << _year << "-" << _month << "-" << _day << endl;
}
void Show2()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
void F1()
{
Show1();
Show2();
}
void F2()const
{
Show1();
//Show2(); //出错,const调用非const成员函数
}
private:
int _year;
int _month;
int _day;
};
1. const对象可以调用非const成员函数? 不可以>权限放大
2. 非const对象可以调用const成员函数吗? 可以>权限缩小3. const成员函数内可以调用其它的const成员函数非const成员函数吗? 可以, 不可以
4. 非const成员函数内可以调用其它的const成员函数非const成员函数吗? 可以 ,可以
类的静态成员:声明为static的类成员(成员数据或成员函数)称为类的静态成员
特征:
1.静态成员为所有类对象所共享,不属于某个具体的实例
2.类静态成员即可用类名::静态成员或者对象.静态成员来访问
3.类静态成员变量必须在类外定义,定义时不添加static关键字
4.类的静态成员函数没有默认的this指针,因此在它里面不能使用任何非静态成员
5.静态成员和类的普通成员一样,也有public、protected、private3种访问级别,也可以具有返回值,const修饰符等参数
#include <iostream>
using namespace std;
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
:_year(year)
,_month(month)
,_day(day)
{
++_count;
}
Date(const Date& d)
:_year(d._year)
,_month(d._month)
,_day(d._day)
{
++_count;
}
void Show() const
{
cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
GetCount();
}
// 没有this指针
static int GetCount()
{
//_year = 10;
//Show();
return _count;
}
private:
int _year;
int _month;
int _day;
static size_t _count;
};
size_t Date::_count = 0;
int main()
{
Date d1(2018, 3, 26);
Date d2(2018, 3, 26);
cout<<d1.GetCount()<<endl;
cout<<d2.GetCount()<<endl;
cout<<Date::GetCount()<<endl; //通过类名访问静态成员函数
return 0;
}
1. 静态成员函数可以访问非静态的成员吗? 不能访问,静态成员函数没有this指针
2. 非静态的成员函数可以访问静态成员吗? 可以访问,通过类域进行访问
再探拷贝构造函数的优化:
在一个步骤中,先构造了一个临时对象,又用该临时对象拷贝构造其他对象,会将二者合二为一
#include <iostream>
using namespace std;
class Date
{
public :
Date()
{
cout<<"Date()" <<endl;
}
Date(const Date& d)
{
cout<<"Date(const Date& d)" <<endl;
}
Date& operator=(const Date& d )
{
cout<<"Date& operator=(const Date& d)"<< endl;
return *this ;
}
~Date()
{
cout<<"~Date()" <<endl;
}
};
void fun1 (const Date& d)
{}
Date fun2()
{
//Date ret;
//return ret; //这里发生拷贝构造临时对象,ret被析构
return Date(); //直接返回匿名对象,优化了拷贝构造
}
void fun3(Date d) //传值,多调用一次拷贝构造,还要调析构
{
}
int main()
{
//情景1
//Date d1;
//fun1(d1); //d1已经存在,不会调用拷贝
//情景2 一次构造,一次析构
//fun3(Date()); //在一个步骤中,先构造了一个临时对象,又用该临时对象拷贝构造其他对象,会将二者合二为一,调用了构造,然后直接进行拷贝构造
//fun1(Date()); //结果相同,意义不同,这里d是Date()的别名
Date d1 = fun2();//fun2中进行一次构造,一次拷贝构造
//Date d2; //构造
//d2 = fun2(); //构造、拷贝构造、赋值运算符重载
//Date d3;
//Date();// 临时对象,匿名对象,声明周期只在当前一行
//Date().Show(); // 临时对象,匿名对象,声明周期只在当前一行,(使用场景:只是调用一下某个对象的某个函数,调完以后不会再
// 用该对象,调用结束,立刻析构)
return 0;
}
#include <iostream>
using namespace std;
class AA
{
public:
AA()
{
cout << "AA()" << endl;
}
AA(const AA& A)
{
cout << "const AA(AA& A)" << endl;
}
AA& operator=(const AA& A)
{
cout << "AA& operator=(const &AA A)" << endl;
return *this ;
}
};
AA f(AA a)
{
return a;
}
void Test1() //二次拷贝构造,1次赋值运算符的重载
{
AA a1;
a1 = f(a1);
}
void Test2() //二次拷贝构造,0次赋值运算符的重载
{
AA a1;
AA a2 = f(a1);
}
void Test3() //三次拷贝构造,0次赋值运算符的重载
{
AA a1;
AA a2 = f(f(a1));
}
int main()
{
printf("test1:\n");
Test1();
printf("test2:\n");
Test2();
printf("test3:\n");
Test3();
return 0;
}