c++中的友元函数

知识点1【const修饰成员函数】

用const修饰成员函数时,const修饰this指针指向的内存区域,成员函数体内不可以修改本类中的任何普通成员变量,当成员变量类型符前用mutable修饰时例外。

int myFun()const//const修饰的是成员函数
{}//函数内部不能修改,普通成员变量mutable修饰时例外
#include <iostream>

using namespace std;

class Data{
private:
    int data;

    mutable int num;
public:
    //遍历 成员的函数 不会去修改成员的值
    //如果函数不会更改成员数据 就让编译器知道 这是一个const函数
    void myPrintData(void) const{
        //data =10000;//err const修饰函数 函数不能操作普通成员变量
        cout << this->data << endl;
        //cout<<data<<endl;

        //mutable修饰的成员变量 可以修改
        num = 200;
    }

    Data(){
        cout<<"无参构造"<<endl;
    }

    Data(int data){
        this->data =data;
        cout<<"有参构造"<<endl;
       }

    Data(const Data &ob){
        this->data = ob.data;
        cout<<"拷贝构造"<<endl;
    }
    ~Data(){
        cout<<"析构函数"<<endl;
    }
};

void test02(){
    Data ob1(100);
    ob1.myPrintData();
}

int main(int argc, char *argv[])
{
    test02();
    return 0;
}

2、const修饰对象,叫做常对象

#include <iostream>

using namespace std;

class Data{
private:
    int data;

    mutable int num;
public:
    //遍历 成员的函数 不会去修改成员的值
    //如果函数不会更改成员数据 就让编译器知道 这是一个const函数
    void myPrintData(void) const{
        //data =10000;//err const修饰函数 函数不能操作普通成员变量
        cout << this->data << endl;
        //cout<<data<<endl;

        //mutable修饰的成员变量 可以修改
        num = 200;
    }

    //对于普通成员函数,编译器认为存在修改成员变量的可能
    void setData(int data) const{

    }

    Data(){
        cout<<"无参构造"<<endl;
    }

    Data(int data){
        this->data =data;
        cout<<"有参构造"<<endl;
       }

    Data(const Data &ob){
        this->data = ob.data;
        cout<<"拷贝构造"<<endl;
    }
    ~Data(){
        cout<<"析构函数"<<endl;
    }
};

void test03(){
    //常对象
    const Data ob1(100);

    //常对象只能调用const修饰的函数,遍历成员数据
    ob1.myPrintData();
}

int main(int argc, char *argv[])
{
    test03();
    return 0;
}

知识点2【友元】

c++允许友元访问私有数据
友元的语法:
friend关键字只出现在声明处,其他类、类成员函数、全局函数都可以声明为友元,友元函数不是类的成员,不带this指针,友元函数可访问对象任意成员属性,包括私有属性。

1、普通全局函数作为类的友元

#include <iostream>

using namespace std;

class Room{
    //将goodGayVisit作为类的友元函数
    //goodGayVisit访问类中的所有数据,但它不是类的成员
    friend void goodGayVisit(Room &room);
private:
    string bedRoom;
public:
    string sittingRoom;
    Room(){
        this->bedRoom = "卧室";
        this->sittingRoom = "客厅";
    }

};

//普通全局函数作为类的友元
//好基友访问我的房间
void goodGayVisit(Room &room){
    cout << "好基友访问了你的" << room.sittingRoom << endl;
    cout << "好基友访问了你的" << room.bedRoom << endl;
}
int main(int argc, char *argv[])
{
    Room myRoom;
    goodGayVisit(myRoom);
    return 0;
}

运行结果:
在这里插入图片描述

2、类的某个成员作为另一个类的友元

问题1:
在这里插入图片描述
问题2:
在这里插入图片描述
问题3:
在这里插入图片描述
终极代码:

#include <iostream>

using namespace std;
class Room;

class goodGay{
public:
    void goodGayVisit(Room &room);
};

class Room{
    //如果将goodGayVisit函数作为Room类的友元,那么就可以访问Room类的私有数据。
    //一定要记得加类作用域
    friend void goodGay::goodGayVisit(Room &room);
private:
    string bedRoom;
public:
    string sittingRoom;
    Room(){
        this->bedRoom = "卧室";
        this->sittingRoom = "客厅";
    }

};

void goodGay::goodGayVisit(Room &room){
    cout << "好基友访问了你的" << room.sittingRoom << endl;
    cout << "好基友访问了你的" << room.bedRoom << endl;
}

int main(int argc, char *argv[])
{
    Room myRoom;
    goodGay goodGay;
    goodGay.goodGayVisit(myRoom);
    return 0;
}

3、一个类的整体作为另一个类的友元

一个类的所有成员函数,访问另一个类的私有数据

#include <iostream>

using namespace std;
class Room;
class goodGay;

class goodGay{
public:
    void goodGayVisit1(Room &room);
    void goodGayVisit2(Room &room);
};

class Room{
    //如果将goodGayVisit函数作为Room类的友元,那么就可以访问Room类的私有数据。
    //一定要记得加类作用域
    friend class goodGay;
    string bedRoom;
public:
    string sittingRoom;
    Room(){
        this->bedRoom = "卧室";
        this->sittingRoom = "客厅";
    }

};

void goodGay::goodGayVisit1(Room &room){
    cout << "好基友访问了你的" << room.sittingRoom << endl;
    cout << "好基友访问了你的" << room.bedRoom << endl;
}

void goodGay::goodGayVisit2(Room &room){
    cout << "好基友访问了你的" << room.sittingRoom << endl;
    cout << "好基友访问了你的" << room.bedRoom << endl;
}

int main(int argc, char *argv[])
{
    Room myRoom;
    goodGay goodGay;
    goodGay.goodGayVisit1(myRoom);
    goodGay.goodGayVisit2(myRoom);
    return 0;
}

知识点3【封装电视机和遥控器的类】

1、封装电视机的类

class TV{
   enum{on,off}; //电视机开关
   enum{minVol,maxVol = 100};//电视机音量,从0到100
   enum{minChannel=1,maxChannel = 255};//频道从0到255
private:
   int mState;//电视机状态
   int mVolume;//电视机音量
   int mChannel;//电视机频道
public:
   TV(){
       this->mState = off;
       this->mVolume = minVol;
       this->mChannel = minChannel;
   }

   void onOroff(){
       this->mState = (this->mState == on? off:on);
   }
   //加大音量
   void volumeUp(){
       if(this->mVolume < maxVol){
           mVolume++;
       }
   }

   //减小音量
   void volumeDown(){
       if(this->mVolume > minVol){
           mVolume--;
       }
   }

   //增加频道
   void channelUp(){
       if(this->mChannel < maxChannel){
            mChannel++;
       }
   }

   //减小频道
   void channelDown(){
       if(this->mChannel > minChannel){
            mChannel--;
       }
   }

   //显示电视机状态
   void showTV(){
       cout << "电视的状态为" << (this->mState == on? "开机":"关机")<<endl;
       cout << "电视机的音量为" << this->mVolume <<endl;
       cout << "电视机的频道为" << this->mChannel <<endl;
   }
};

int main(int argc, char *argv[])
{
    TV tv = TV();
    tv.onOroff();
    tv.volumeUp();//调四次音量
    tv.volumeUp();
    tv.volumeUp();
    tv.volumeUp();

    tv.channelUp();//调两次频道
    tv.channelUp();
    tv.showTV();
    return 0;
}

运行结果:
在这里插入图片描述

2、设置遥控器的类

class TV{
   friend class Remote;

   enum{on,off}; //电视机开关
   enum{minVol,maxVol = 100};//电视机音量,从0到100
   enum{minChannel=1,maxChannel = 255};//频道从0到255
private:
   int mState;//电视机状态
   int mVolume;//电视机音量
   int mChannel;//电视机频道
public:
   TV(){
       this->mState = off;
       this->mVolume = minVol;
       this->mChannel = minChannel;
   }

   void onOroff(){
       this->mState = (this->mState == on? off:on);
   }
   //加大音量
   void volumeUp(){
       if(this->mVolume < maxVol){
           mVolume++;
       }
   }

   //减小音量
   void volumeDown(){
       if(this->mVolume > minVol){
           mVolume--;
       }
   }

   //增加频道
   void channelUp(){
       if(this->mChannel < maxChannel){
            mChannel++;
       }
   }

   //减小频道
   void channelDown(){
       if(this->mChannel > minChannel){
            mChannel--;
       }
   }

   //显示电视机状态
   void showTV(){
       cout << "电视的状态为" << (this->mState == on? "开机":"关机")<<endl;
       cout << "电视机的音量为" << this->mVolume <<endl;
       cout << "电视机的频道为" << this->mChannel <<endl;
   }
};


class Remote{
private:
    TV *pTV;
public:
    Remote(TV *pTV){
        this->pTV = pTV;
    }
    //音量的加减
    void volumeUp(void){
        this->pTV->volumeUp();
    }

    void volumeDown(void){
        this->pTV->volumeDown();
    }

    //频道的加减
    void channelUp(void){
        this->pTV->channelUp();
    }

    void channelDown(void){
        this->pTV->channelDown();
    }

    //电视开关
    void onOrOff(void){
        this->pTV->onOroff();
    }

    //遥控器频道的设置
    void setChannel(int num){
        //判断频道是否有效
        if(num <= TV::maxChannel && num >= TV::minChannel){
            this->pTV->mChannel = num;
        }
    }

    //遥控器音量的设置
    void setVolume(int num){
        if(num <= TV::maxVol && num >= TV::minVol){
            this->pTV->mVolume = num;
        }
    }

    void showTV(void){
        this->pTV->showTV();
    }

};



int main(int argc, char *argv[])
{
    TV tv = TV();
    tv.onOroff();
    tv.volumeUp();//调四次音量
    tv.volumeUp();
    tv.volumeUp();
    tv.volumeUp();

    tv.channelUp();//调两次频道
    tv.channelUp();
    tv.showTV();

    Remote remote = Remote(&tv);
    remote.volumeUp();
    remote.channelUp();
    remote.showTV();

    remote.setChannel(10);
    remote.setVolume(15);

    remote.showTV();

    return 0;
}

运行结果:
在这里插入图片描述

知识点4【强化类的封装】

myarray.h

#ifndef MYARRAY_H
#define MYARRAY_H


class MyArray
{
private:
    int capacity;//数组总共存放的元素的个数
    int size;//数组实际存放的元素个数
    int *addr;//数组首元素地址
public:
    MyArray();
    MyArray(int capacity);
    ~MyArray();

    //往数组的尾部插入数据
    void pushBack(int data);
    //获得指定位置的数据
    int getData(int pos);
    //修改指定位置的值
    void setData(int pos,int data);
    //获取数组的容量(能存放的最大元素个数)
    int getCapacity(void);
    //获取数组的实际大小(实际元素的个数)
    int getSize(void);
    //打印数组
    void printMyArray(void);
};

#endif // MYARRAY_H

myarray.cpp

#include <iostream>
#include "myarray.h"

using namespace std;

MyArray::MyArray()
{
    this->capacity = 15;//数组总共存放的元素的个数
    this->size = 0;//数组实际存放的元素个数
    addr = new int[this->capacity];//数组首元素地址
}

MyArray::MyArray(int capacity)
{
    this->capacity = capacity;//数组总共存放的元素的个数
    this->size = 0;//数组实际存放的元素个数
    addr = new int[this->capacity];//数组首元素地址
}

MyArray::~MyArray()
{
	if(this>addr != NULL){
		delete [] this>addr;
		this>addr = NULL;
	}
}

void MyArray::pushBack(int data){
    if(this->size >= this->capacity){
        cout<<"数组已满"<<endl;
        return;
     }
     addr[this->size] = data;
     this->size++;

}

int MyArray::getData(int pos){
    if(pos >= this->size) {
        cout <<"位置无效" << endl;
        return -1;
    }

    return addr[pos];
}

void MyArray::setData(int pos, int data){
    if(pos >= this->size) {
        cout <<"位置无效" << endl;
        return;
    }
addr[pos] = data;
}

int MyArray::getCapacity(){
    return this->capacity;
}

int MyArray::getSize(){
    return this->size;
}

void MyArray::printMyArray(){
    int i=0;
    for(i=0;i<this->size; i++){
        cout<<this->addr[i]<<" ";
    }
    cout<<endl;
}

main.cpp

#include <iostream>
#include "myarray.h"

using namespace std;

int main(int argc, char *argv[])
{
    MyArray arr1;
    cout<<"容量:"<<arr1.getCapacity()<<endl;
    cout<<"大小:"<<arr1.getSize()<<endl;

    MyArray arr2(50);
    cout<<"容量:"<<arr2.getCapacity()<<endl;
    cout<<"大小:"<<arr2.getSize()<<endl;

    //往数组中插入20个数据
    int i=0;
    for(i=0;i<20;i++){
        arr2.pushBack(i);
    }
    cout<<"容量:"<<arr2.getCapacity()<<endl;
    cout<<"大小:"<<arr2.getSize()<<endl;
    //遍历数组
    arr2.printMyArray();

    //更改pos=9的值 2000
    arr2.setData(9,2000);
    arr2.printMyArray();

    //得到下标为9的值
    cout<<arr2.getData(9)<<endl;//
    return 0;
}

运行结果:
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值