【C++学习】5、类的补充

一、类的大小

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;
}
  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值