C++友元函数

1、友元概念:

1、打破了C++的封装性(运算符重载也会)

2、声明友元的关键字是friend,friend只会出现在声明除

3、友元函数不是类的成员,不带this指针,友元函数可以访问对象任意成员属性,包括私有属性

2、全局函数称为友元:


#include <iostream>

using namespace std;

class room
{
     friend void getroom(room &room1);
private:
    string bedroom;
public:

    string livingroom;

};
void getroom(room &room1)
{
    cout<<room1.bedroom<<endl;
    cout<<room1.livingroom<<endl;

}

void test04()
{
    room room1;
    getroom(room1);
}

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

3、成员函数作为友元:

class Room; //向前声明Room类,但并不知道类内部的成员
//作为友元类的定义,必须定义在最上方(友元类就是包含成员函数的类)
//友元类的成员函数必须在所有类的最下方定义
class GoodGay
{
private:
public:
    GoodGay()
    {
    }
    void visitroom01(Room & room);
    void visitroom02(Room & room);
};
class Room
{
   // friend void GoodGay::visitroom01(Room &room);
    friend void GoodGay::visitroom02(Room &room);  ///< 友元只能出现在声明处
private:
    string bedroom;
public:
    Room(string bed, string living)
    {
        bedroom = bed;
        livingroom = living;
    }
    string livingroom;
};
void GoodGay::visitroom01(Room & room)
{
        //cout << "访问" << room.bedroom << endl;
        cout << "访问" << room.livingroom << endl;
}
void GoodGay::visitroom02(Room & room)
{
        cout << "访问" << room.bedroom << endl;
        cout << "访问" << room.livingroom << endl;
}
void test01()
{
    Room room("卧室", "客厅");
    GoodGay gay;
    gay.visitroom01(room);
    gay.visitroom02(room);
}

4、类作为友元函数:


#include <iostream>

using namespace std;

class Room; //向前声明Room类,但并不知道类内部的成员
//作为友元类的定义,必须定义在最上方(友元类就是包含成员函数的类)
//友元类的成员函数必须在所有类的最下方定义
class GoodGay
{
private:
public:
    GoodGay()
    {
    }
    void visitroom01(Room & room);
    void visitroom02(Room & room);
};
class Room
{

        friend class GoodGay;
        //直接友元类
private:
    string bedroom;
public:
    Room(string bed, string living)
    {
        bedroom = bed;
        livingroom = living;
    }
    string livingroom;
};
void GoodGay::visitroom01(Room & room)
{
        cout << "访问" << room.bedroom << endl;
        cout << "访问" << room.livingroom << endl;
}
void GoodGay::visitroom02(Room & room)
{
        cout << "访问" << room.bedroom << endl;
        cout << "访问" << room.livingroom << endl;
}
void test01()
{
    Room room("卧室", "客厅");
    GoodGay gay;
    gay.visitroom01(room);
    gay.visitroom02(room);
}
int main(int argc, char *argv[])
{
    test01();
    return 0;
}

友元函数注意:

1、友元关系不能继承

2、友元关系是单向的,类A是类B的朋友,但类B不一定是A的朋友。

3、友元关系不具备传递性。类B是类A的朋友,类C是类B的朋友,但类A不一定是类C的朋友。

例1:电视机类的实现(电视机有开机和关机状态,有音量,有频道,提供音量操作的方法,频道操作的方法。 由于电视机只能逐一调整频道,不能指定频道)

//第一步分析类中的成员函数和成员变量
//成员变量电视状态,音量,频道,成员函数有音量操作,频道操作,开关操作。

#include <iostream>

using namespace std;
class tv
{   enum
    {
        minchannel = 1,
        maxchannel = 100
        //枚举出电视频道。
    };
    enum
    {
        minvoice = 0,
        maxvoice = 100
        //枚举出电视音量。
    };
private:
    bool state;
    //电视只有俩种状态,开,关
    int voice;
    int channel;

public:
    tv()
    {
        state = false;
        voice = minvoice;
        channel = minchannel;
        //电视的初始状态。
    }

    tv(bool state,int voice,int channal)
    {
        //初始化开机状态
        this->state = state;
        this->voice = voice;
        this->channel = channal;
    }
    tv(const tv &ob)
    {
       this->state = ob.state;
       this->voice = ob.voice;
       this->channel = ob.channel;
    }

    void onoff();//显示开关机状态
    void setvoice();//显示音量状态
    void setchannel();//显示频道状态

};
void test01()
{
    tv tv1(true,101,101);
    //调用有参构造,打开电视机,设置三个不同的状态
    tv1.onoff();
    tv1.setvoice();
    tv1.setchannel();
}

void tv::onoff()
{
    bool b =(state? true:false);
    cout<<"the state of tv is"<<" "<<b<<endl;
    //电视是开会输出1,关输出0
}

void tv::setvoice()
{

    if((this->voice) >= minvoice && (this->voice) <= maxvoice)
    {
         cout<<"现在的音量是"<<this->voice<<endl;
    }

    if((this->voice) >maxvoice)
    {
         cout<<"voice is max"<<endl;
            return;
    }
       this->voice++;
}

void tv::setchannel()
{

    if(this->channel >= minchannel && this->channel <= maxchannel)
    {
        cout<<"现在的频道是"<<this->channel<<endl;
    }
                this->channel++;

    if(this->channel > maxchannel+1)
    {

              this->channel = minchannel;
       cout<<"现在的频道是"<<this->channel<<endl;
       return;
    }

}

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

例2:实现遥控器对电视的控制(遥控器类的实现)

//第一步分析类中的成员函数和成员变量
//成员变量电视状态,音量,频道,成员函数有音量操作,频道操作,开关操作。

#include <iostream>
using namespace std;
class tv;
class remote
//遥控器类
{

private:
    tv *p1;
    //遥控器中声明一个tv中的指针,方便传入电视的数据
public:
    remote(tv*tv1)
    //接收传入的tv指针
    {
        p1 =tv1;
        //初始化
    }
    void onof(tv*p1);
    void setvoice(tv*p1);
    void setchannel(tv*p1);
    //上面三个函数方便调用tv的状态
    void setchannelnum(tv*p1,int num);
    //遥控器可以改变tv的频道
};
class tv
{
    friend class remote;
    enum{minchannel = 1,maxchannel = 100};
    enum{minvoice = 0,maxvoice = 100};
private:
    bool state;
    int voice;
    int channel;
public:
    tv()
    {   
        //tv的初始状态
        state = false;
        voice = minvoice;
        channel = minchannel;
    }
    tv(bool on,int voice,int channel)
    {   
        //实例化只会的状态
        this->state = on;
        this->voice = voice;
        this->channel =channel;
    }
    tv(const tv&ob)
    {   
        //有指针要拷贝构造
        this->state = ob.state;
        this->voice = ob.voice;
        this->channel = ob.channel;
    }
    void onof();
    void setvoice();
    void setchannel();
    //tv自己的三个状态函数
};
void test01()
{
    tv tv1(true,40,3);
    //实例化后开机的状态
    tv1.onof();
    tv1.setchannel();
    tv1.setvoice();
    //上面三个函数可以表现出tv的三个状态

    remote remote1(&tv1);
    //实例化一个遥控器类,传入tv的指针初始化
    remote1.onof(&tv1);
    remote1.setchannelnum(&tv1,20);
    //改变tv的频道
    remote1.setchannel(&tv1);
    remote1.setvoice(&tv1);
    //显示出遥控器关于电视的三个状态
}
void tv::onof()
{
    bool b =(state?true:false);
    cout<<"the state of tv is"<<" "<<b<<endl;
    //判断传入的第一个参数true为1开机状态,flase为0关闭状态
}
void tv::setvoice()
{
    if(voice == maxvoice)
    {
        cout<<"声音最大"<<endl;
        return;
    }
    this->voice++;
    cout<<"音量为"<<this->voice<<endl;
}
void tv::setchannel()
{
    if(this->channel == maxchannel)
    {
        cout<<"频道最大"<<endl;
        this->channel = 0;
        return;
    }
    this->channel++;
    cout<<"频道为"<<" "<<this->channel<<endl;

}
void remote::onof(tv *p1)
{
    cout<<"the state of tv is"<<p1->state<<endl;
}
void remote::setvoice(tv *p1)
{
    p1->setvoice();
}

void remote::setchannelnum(tv *p1, int num)
{
    p1->channel = num;
    //遥控器改变频道
}
void remote::setchannel(tv *p1)
{
    p1->setchannel();
    //打印出现在的频道
}

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

5、动态数组:

//动态数组,确定数组中成员变量:数组容量大小,存放在里面数组的长度,指向数组开头的指针
//成员函数,判断数组是否满了,满了扩大,并且在末尾添加数据。删除末尾的元素,判断元素个数是否为0。最后遍历

#include <iostream>
#include<stdlib.h>
using namespace std;
class arr
{
private:
    int *p;
    //有指针要自定义拷贝构造
    int size;
    int capacity;
    //三个成员变量
public:
    arr()
    {   //初始化最初的数组大小,分配空间,和容量
        p = new int[5];
        this->size = 0;
        this->capacity = 5;
    }
    arr(int *p,int size,int capacity)
    {
        this->p = p;
        this->size = size;
        this->capacity =capacity;
    }
    arr(const arr &ob)
    {
        capacity = ob.capacity;
        this->p = new int[capacity];
        //当前的指针开辟空间。
        this->size = ob.size;
        memcpy(this->p,ob.p,size*sizeof(int));
        //把旧对象的数组的内容,cpy到新对象中。
    }
    ~arr()
    {
        if(p != nullptr)
        {
           delete []p;
        }
        p =nullptr;
    }
    void push(int newnum);
    void pop();
    void print();

};
void test01()
{
   arr arr1;
   arr1.push(10);
   arr1.push(20);
   arr1.push(30);
   arr1.print();
   cout<<endl;
   //在数组中先插入三个元素打印

   arr1.pop();
   arr1.pop();
   //删除了初始化的最后俩二元素
   arr1.push(40);
   arr1.push(50);
   arr1.push(60);
   arr1.push(70);
   arr1.push(80);
   arr1.push(90);
   arr1.print();
}

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

void arr::push(int newnum)
{   //先判断容量是不是为满了
    if(capacity == size)
    {
        int *temp =new int[2*capacity];
        //满了就定义一个零时指针开辟俩倍空间。
        memcpy(temp,p,size*sizeof(int));
        //把之前的内容拷贝到零时指针。
        delete[]p;
        p = temp;
        capacity = 2*capacity;
    }
    p[size] =newnum;
    //尾插法
    size++;
}

void arr::pop()
{   //调用一次删除一个最后的数组元素
    if(size == 0)
    {
        cout<<"数组是空的"<<endl;
        return;
    }
    size--;
}

void arr::print()
{
    for(int i =0;i<size;i++){
        cout<<p[i]<< " ";

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值