一、类的大小
1、静态成员、成员函数不占类的空间
2、类的对齐规则和结构体的对齐规则一致
二、this指针
1、什么是this指针?
1、普通成员函数内部自带一个隐式的this指针变量
2、this保存的是调用该成员函数的对象的地址
2、如果成员函数的形参名和数据成员名同名,可以使用this指针区分
class Data
{
public:
int a;
public:
void setA(int a)
{
this->a = a;
}
};
3、通过this完成链式操作
class Print
{
public:
Print& PrintStr(char *str)
{
cout<<str;
//this 表示调用该成员函数的对象的地址
//*this 表示调用该成员函数的对象
return *this;
}
};
4、静态成员函数没有this指针
静态成员函数是属于类,二不是对象,可以直接通过类名调用。和对象没有关系,所有静态成员内部没有this指针。
5、const修饰的成员函数内部不能对成员数据写操作,mutable修饰的成员数据 除外
class Data1
{
public:
int a;
mutable int b;
public:
//const修饰成员函数
void showData(void) const
{
//a = 100;//err
b = 200;//ok
cout<<"a="<<a<<", b="<<b<<endl;
}
};
三、友元函数
1、什么是友元函数?
关键字:friend
不通过类的成员函数直接访问类的私有数据,破坏了类的封装性
特殊的运算符重载,会用到友元
2、友元的分类
1、普通全局函数作为类的友元
2、类的成员函数作为另一个类的友元
A类的成员函数作为B类的友元
1、A类必须在B类之前定义
2、A类的成员函数必须在类外(必须是B类的下发实现)
3、记得将B类向前声明
3、整个类作为另一个类的友元
注意:
1、友元关系不能被继承
2、友元关系是单向的,类A是类B的朋友,但类B不一定是类A的朋友
3、友元关系不具有传递性
案例:
#include<iostream>
using namespace std;
class remote;
//编写电视机类,电视机有开机和关机状态,有音量,有频道,提供音量操作的方法,频道操作的方法。
class tv
{
friend class remote;
enum{OFF,ON};//开关机状态
enum{minVol,maxVol=100};//音量
enum{minChan=1,maxChan=20};//频道
private:
int state;
int volume;
int channel;
public:
tv()
{
state=OFF;
volume=minVol;
channel=minChan;
}
void setOfforOn();//电视操作方法
void volumeUp();
void volumeDown();//音量操作方法
void channelUp();
void channelDown();//频道操作方法
void showTv();
};
//由于电视机只能逐一调整频道,不能指定频道,增加遥控类,遥控类除了拥有电视机已有的功能,再增加根据输入调台功能。
//提示:遥控器可作为电视机类的友元类
class remote
{
private:
tv *p;
public:
remote(tv *p)
{
this->p=p;
}
void setOfforOn();//电视操作方法
void volumeUp();
void volumeDown();//音量操作方法
void channelUp();
void channelDown();//频道操作方法
void showTv();
void setChannal(int channel);
};
int main()
{
tv t;
remote re(&t);
re.setOfforOn();
re.setChannal(20);
re.volumeUp();
re.volumeUp();
re.volumeUp();
re.volumeUp();
re.showTv();
return 0;
}
void tv::setOfforOn()
{
state=(state==OFF?ON:OFF);
}
void tv::volumeUp()
{
if(volume==maxVol)
{
cout<<"音量乙最大"<<endl;
return;
}
volume++;
}
void tv::volumeDown()
{
if(volume==minVol)
{
cout<<"音量已最小"<<endl;
return;
}
volume--;
}
void tv::channelUp()
{
if(channel==maxChan)
{
cout<<"频道已最大"<<endl;
return;
}
channel++;
}
void tv::channelDown()
{
if(channel==minChan)
{
cout<<"频道已最小"<<endl;
return;
}
channel--;
}
void tv::showTv()
{
cout<<(state==OFF?"点击关闭":"电视已开")<<endl;
cout<<"当前电视机音量:"<<volume<<endl;
cout<<"当前电视机频道:"<<channel<<endl;
}
void remote::setOfforOn()
{
p->setOfforOn();
}
void remote::volumeUp()
{
p->volumeUp();
}
void remote::volumeDown()
{
p->volumeDown();
}
void remote::channelUp()
{
p->channelUp();
}
void remote::channelDown()
{
p->channelDown();
}
void remote::showTv()
{
p->showTv();
}
void remote::setChannal(int channel)
{
if(channel < tv::minChan || channel>tv::maxChan)
{
cout<<"无效的频道"<<endl;
return;
}
p->channel = channel;
}
四、运算法重载
1、什么是运算符重载?
运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。
关键字:operator
2、什么时候用运算符重载?
1、确定运算符的运算对象的个数
2、运算符左边的运算对象是自定义对象
是自定义对象:
全局函数实现运算符重载;
成员函数实现运算符重载
其他:
只能全局函数实现
运算符重载的目的:让代码更容易读、写
例:重载运算法<<
//全局函数实现 记得将其设置成友元
ostream& operator<<(ostream &out , Person &ob)
{
out<<ob.num<<" "<<ob.name<<" "<<ob.score<<endl;
return out;
}