C++ 语言学习 day10 复习(2)

1.友元 的三种形式 

 /*********** 友元 ************
 * ①全局函数做友元
 * ②类做友元
 * ③类成员函数做友元
 * **************************/

代码:

#include 
#include 
using namespace std;

/* ③类函数友元 : 程序规则{ 自上而下,从左往右 }*/
class House;    /*提前空声明*/

class Auntie
{
public:
    /*** 注意:是类内声明,类外实现(在被友元类后类外实现) ***/
    void cleaning(House value);  /* 保洁|清洁 函数 ---> 想让该函数做友元*/
    void burning(House value);   /* 烧房子函数  ---> 不想让该函数做友元*/
};
/*********** 友元 ************
 * ①全局函数做友元
 * ②类做友元
 * ③类成员函数做友元
 * **************************/
class House
{
    /***** 全局友元函数:友元声明 ******/
    friend void detection(House value);

    /***** 类:友元声明 *****/
    friend class Girls;

    /***** 类函数:友元声明 ****/
    friend void Auntie::cleaning(House value);
    //friend void Auntie::burning(House value);  不想让该函数为友元
public:
    int m_corridor = 1;  /*走廊*/
protected:
    int m_parlor = 2;    /*客厅*/
private:
    int m_bedroom = 3;   /*卧室*/
};

/* ①全局友元函数 */
void detection(House value)
{
    cout << "\n————————————————————————————————————————" << endl;
    cout << "检测走廊:" << value.m_corridor << endl;
    cout << "检测客厅:" << value.m_parlor << endl;
    cout << "检测卧室:" << value.m_bedroom << endl;
}

/* ②类友元 */
class Girls /*闺蜜类*/
{
public:
    static void visit(House value)
    {
        cout << "\n————————————————————————————————————————" << endl;
        cout << "参观走廊:" << value.m_corridor << endl;
        cout << "参观客厅:" << value.m_parlor << endl;
        cout << "参观卧室:" << value.m_bedroom << endl;
    }

    int GetBedroom()const
    {
        return this->house.m_bedroom;   /* 参观卧室 */
    }

    House house;    /* 当成成员 */
};

/* ③类函数友元 : 程序规则{ 自上而下,从左往右 } ,需要在被友元类之后类外实现*/
void Auntie::cleaning(House value) /* 类友元函数 */
{
    cout << "\n————————————————————————————————————————" << endl;
    cout << "清洁走廊:" << value.m_corridor << endl;
    cout << "清洁客厅:" << value.m_parlor << endl;
    cout << "清洁卧室:" << value.m_bedroom << endl;
}

void Auntie::burning(House value) /* 非类友元函数 */
{
    cout << "\n————————————————————————————————————————" << endl;
//    cout << "烧走廊:" << value.m_corridor << endl;
//    cout << "烧客厅:" << value.m_parlor << endl;
//    cout << "烧卧室:" << value.m_bedroom << endl;
}



int main()
{
    /* 1.实例化对象 */
    House house;

    /* 2.调用友元 */
    /* 2.1 调用全局友元函数 */
    detection(house);

    /* 2.2 调用友元类 */
    Girls girls;
    girls.visit(house);
    cout << "参观卧室:" << girls.GetBedroom() << endl;

    /* 2.3 调用类友元函数 */
    Auntie auntie;
    auntie.cleaning(house); /* 调用类友元函数 : 清洁 */
    auntie.burning(house);  /* 调用非类友元函数:烧房子*/
    return 0;
}

2.运算符号重载  (简单)


/******** 运算符重载 **********************************************
 * 支持: 类外 和 类内
 * 注意: 调用直接使用运算符时不能同时存在类内和类外定义,只能存其一
 *      如果按照本质调用则可以同时存在
 *
 * —————————————————————— 本质调用 
 * 类外:实现的时候,必须(满参数),直接调用函数名
 * 类内:类内实现,第一个参数不用填,使用this代替,直接调用函数名
 * —————————————————————— 套路规则
 * 一般情况提供类内运算符重载,且{类内声明,类内实现},不提倡{类内声明类外实现}

代码:

#include 

using namespace std;

/******** 运算符重载 **********************************************
 * 支持: 类外 和 类内
 * 注意: 调用直接使用运算符时不能同时存在类内和类外定义,只能存其一
 *      如果按照本质调用则可以同时存在
 *
 * —————————————————————— 本质调用 ——————————————————————
 * 类外:实现的时候,必须(满参数),直接调用函数名
 * 类内:类内实现,第一个参数不用填,使用this代替,直接调用函数名
 * —————————————————————— 套路规则 ——————————————————————
 * 一般情况提供类内运算符重载,且{类内声明,类内实现},不提倡{类内声明类外实现}
 * **************************************************************/
class People
{
public:
    People(string name = "",int age = 0):m_name(name),m_age(age){} /* 构造函数 */
public:
    string m_name;  /*姓名*/
    int m_age;      /*年龄*/
private:
    string m_sex;   /*性别*/
public:
    People operator +(People value2) /*类内声明,类内实现*/
    {
        People temp;

        temp.m_name = this->m_name + value2.m_name;
        temp.m_age = this->m_age + value2.m_age;

        return temp;
    }
};


#if 0/**** 类外运算符重载 ***  假如这里要使用需要在类里面  加友元函数 */
People operator +(People value1,People value2)  /*调用类外本质:如果按照本质调用则可以同时存在*/
{
    People temp;

    temp.m_name = value1.m_name + value2.m_name;
    temp.m_age = value1.m_age + value2.m_age;
    temp.m_sex = value1.m_sex + value2.m_sex;

    return temp;
}
#endif


int main()
{
    People people1("张三",18);
    People people2("李四",18);
    People people3;

    /***** 1.直接调用运算符(由C++编译器给你选择) *****/
    //people3 = people1 + people2;  /* 调用直接使用运算符时不能同时存在类内和类外定义,只能存其一 */

    /***** 2.调用类外函数名 *****/
    people3 = operator +(people1,people2);  /*调用类外本质:如果按照本质调用则可以同时存在*/

    /***** 3.调用类内函数名 ******/
    //people3 = people1.operator +(people2);  /* 张三 + 李四 */
    //people3 = people2.operator +(people1);  /* 李四 + 张三 */

    cout << "姓名:" << people3.m_name << "\t年龄:" << people3.m_age << endl;
    return 0;
}

3.运算符重载  (复杂)

重载的函数有  :

/* 四则运算重载 */    (参数的 const  是防止在函数里面改变 数据的值  后面的const 是把函数定义为常量函数,(常量对象只能调用常量函数,别的成员函数都不能调用。 )   ,参数的 &  是一个小的技巧,因为 指针是 4 个字节,  而 类的字节可能 很大!!)

People operator +(const People &value2) const  

 People operator -(const People &value2) const

 People operator *(const People &value2) const

 People operator /(const People &value2) const

 People operator %(const People &value2) const

 /* 四则运算重载,非同类型高阶重载 */  (这里参数不使用指针的原因是 int 类型的字节也是 4个字节)

 People operator +(int age) const

People operator +(string name) const

/* 赋值运算符 */

void operator =(const People &value2)

void operator +=(const People &value2)

void operator -=(const People &value2)

void operator /=(const People &value2)

 void operator *=(const People &value2)

 void operator %=(const People &value2)

/* 赋值运算符,非同类型高阶重载*/

 void operator =(string name)

  void operator =(int age) //使用 等于符号改变  age 的值

/* 关系运算符 */

 bool operator ==(const People &value2)

bool operator !=(const People &value2)

/* 关系运算符,非同类型高阶重载*/

bool operator ==(string name)

/*单目运算符: ++,--(前置和后置的区分,后置需要一个int占位) */

(为什么前置 加了 引用     因为前置需要返回已经改变的  类参数, 后置是返回 没有改变的类参数

i=1;

++i = 2;

i++ =1;

People &operator ++()   //前置  (前++ )

People &operator --()    //前置

const People operator ++(int) //后置

 const People operator --(int) //后置

/*  单目运算符: << , >> , & , | ^          */

  People operator <<(int num)

  People operator >>(int num)

 People operator &(int num)

/* 单目运算符 高阶: << , >> , & , | ^ */  (这里有点难 )

  /****** 由于遇到了 extern ostream cout 整个程序只有一个流,所以需要权限和引用 */

 friend ostream &operator <<(ostream &out,const People &value)   (这里的第二个参数可以不要 &  , 但是加了  &  可以减少字节的运用!!)

 friend istream &operator >>(istream &in,People &value)    (这里第二个参数必须使用  &  因为这里是局部变量需要使用引用, 来改变值, 没有引用的话,我们的参数就不会改变 )

 /* 其他运算符操作: () 仿函数,通常做算法策略 */

   void operator ()(/*参数列表*/)

    bool operator ()(int value) /* 一元谓词 */

   bool operator ()(int value1,int value2) /* 二元谓词 */

 /* 其他运算符操作: [ ] */

 int &operator [](int index) //重载中括号

 const int operator [](string com)    //const 返回的零时变量不可以被改变,就像 ((i++)++)不可以一样。(不能无限套娃!!)             但是 (++(++i))可以无限套娃!!

 /* 其他运算符操作 : -> 很明显是指针操作*/  //重载指针

  Grade *operator ->()

C++ 语言学习 day10 复习(2)_第1张图片

 


People.h

#ifndef PEOPLE_H
#define PEOPLE_H
#include 
#include 
using namespace std;

class People
{
public:
    People(string name = "",string sex = "女",int age = 0); /*构造函数*/
public:
    string m_name;
    string m_sex;
    int m_age;
public:
    void Print();   /*打印参数信息*/
public: /* 四则运算重载 */
    People operator +(const People &value2) const
    {
       People temp;

       temp.m_age = this->m_age + value2.m_age;
       temp.m_name = this->m_name + value2.m_name;
       temp.m_sex = this->m_sex + value2.m_sex;

       return temp;
    }
    People operator -(const People &value2) const
    {
       People temp;

       temp.m_age = this->m_age - value2.m_age;
       temp.m_name = this->m_name + value2.m_name;
       temp.m_sex = this->m_sex + value2.m_sex;

       return temp;
    }
    People operator *(const People &value2) const
    {
       People temp;

       temp.m_age = this->m_age * value2.m_age;
       temp.m_name = this->m_name + value2.m_name;
       temp.m_sex = this->m_sex + value2.m_sex;

       return temp;
    }
    People operator /(const People &value2) const
    {
       People temp;

       temp.m_age = this->m_age / value2.m_age;
       temp.m_name = this->m_name + value2.m_name;
       temp.m_sex = this->m_sex + value2.m_sex;

       return temp;
    }
    People operator %(const People &value2) const
    {
       People temp;

       temp.m_age = this->m_age % value2.m_age;
       temp.m_name = this->m_name + value2.m_name;
       temp.m_sex = this->m_sex + value2.m_sex;

       return temp;
    }

public: /* 四则运算重载,非同类型高阶重载 */
    People operator +(int age) const
    {
       People temp;

       temp.m_age = this->m_age + age;
       temp.m_name = this->m_name;
       temp.m_sex = this->m_sex;

       return temp;
    }
    People operator +(string name) const
    {
       People temp;

       temp.m_age = this->m_age;
       temp.m_name = this->m_name + name;
       temp.m_sex = this->m_sex;

       return temp;
    }

public: /* 赋值运算符 */
    void operator =(const People &value2)
    {
        this->m_age = value2.m_age;
        this->m_sex = value2.m_sex;
        this->m_name = value2.m_name + "牛逼的王";
    }
    void operator +=(const People &value2)
    {
        this->m_age += value2.m_age;
        this->m_sex += value2.m_sex;
        this->m_name += value2.m_name + "牛逼的王";
    }
    void operator -=(const People &value2)
    {
        this->m_age -= value2.m_age;
        this->m_sex = value2.m_sex;
        this->m_name = value2.m_name + "牛逼的王";
    }
    void operator /=(const People &value2)
    {
        this->m_age /= value2.m_age;
        this->m_sex = value2.m_sex;
        this->m_name = value2.m_name + "牛逼的王";
    }
    void operator *=(const People &value2)
    {
        this->m_age *= value2.m_age;
        this->m_sex = value2.m_sex;
        this->m_name = value2.m_name + "牛逼的王";
    }
    void operator %=(const People &value2)
    {
        this->m_age %= value2.m_age;
        this->m_sex = value2.m_sex;
        this->m_name = value2.m_name + "牛逼的王";
    }
public: /* 赋值运算符,非同类型高阶重载*/
    void operator =(string name)
    {
        this->m_name = name;
    }
    void operator =(int age)
    {
        this->m_age = age;
    }

public: /* 关系运算符 */
    bool operator ==(const People &value2)
    {
        if(this->m_name == value2.m_name&&this->m_age == value2.m_age&&this->m_sex == value2.m_sex)
        {
            return true;    /*真*/
        }

        return false;   /*假*/
    }
    bool operator !=(const People &value2)
    {
        if(this->m_age != value2.m_age)
        {
            return true;    /*真*/
        }

        return false;   /*假*/
    }
public: /* 关系运算符,非同类型高阶重载*/
    bool operator ==(string name)
    {
        if(this->m_name == name)
        {
            return true;    /*真*/
        }

        return false;   /*假*/
    }

public: /* 单目运算符: ++,--(前置和后置的区分,后置需要一个int占位) */
    People &operator ++()
    {
        this->m_age += 1;
        return *this;
    }
    People &operator --()
    {
        this->m_age -= 1;
        return *this;
    }
    const People operator ++(int)
    {
        /***********People temp(*this) 解释********
        *People value1;           //变量
        *People *ptr = new People;//指针

        *People value2(value1); //拷贝构造 - 变量
        *People value2(*ptr);   //拷贝构造 - 指针
        * ________________________________________
        *this 是指针 , *指针 === 变量
        ******************************************/
        People temp(*this); /* 拷贝构造 */

        this->m_age += 1;

        return temp;
    }
    const People operator --(int)
    {
        People temp(*this);

        this->m_age -= 1;

        return temp;
    }

public: /* 单目运算符: << , >> , & , | ^ */
    People operator <<(int num)
    {
        People temp(*this);

        temp.m_age = temp.m_age << num;

        return temp;
    }
    People operator >>(int num)
    {
        People temp(*this);

        temp.m_age = temp.m_age >> num;

        return temp;
    }
    People operator &(int num)
    {
        People temp(*this);

        temp.m_age = temp.m_age & num;

        return temp;
    }

public: /* 单目运算符 高阶: << , >> , & , | ^ */
    /****** 由于遇到了 extern ostream cout 整个程序只有一个流,所以需要权限和引用 */
    friend ostream &operator <<(ostream &out,const People &value)
    {
        out << value.m_name << "\t"
            << value.m_age << "\t"
            << value.m_sex;

        return out;
    }
    /****** 由于遇到了 extern istream cin 整个程序只有一个流,所以需要权限和引用 */
    friend istream &operator >>(istream &in,People &value)
    {
        cout << "请输入姓名 性别 年龄:";
        in >> value.m_name >> value.m_sex >> value.m_age;

        return in;
    }

public: /* 其他运算符操作: () 仿函数,通常做算法策略 */
    void operator ()(/*参数列表*/)
    {
        cout << "仿函数策略" << endl;
    }
    bool operator ()(int value) /* 一元谓词 */
    {
        if(value == 1) return true;
        return false;
    }
    bool operator ()(int value1,int value2) /* 二元谓词 */
    {
        if(value1 == value2) return true;
        return false;
    }
public: /* 其他运算符操作: [] */
    int addr[10] = {0};
    int addr_len = -1;  /*当前使用的长度*/
    int addr_max = 10;  /*最大长度*/

    int &operator [](int index)
    {
        return this->addr[index];
    }

    const int operator [](string com)
    {
        if(com == "max") return addr_max;
        if(com == "len") return addr_len;

        return 0;
    }
public: /* 其他运算符操作 : -> 很明显是指针操作*/
    /**** 类内部类 ****/
    class Grade
    {
    public:
        int language;   /*语文成绩*/
        int math;       /*数学成绩*/
    };
    /**** 定义变量 ***/
    Grade grade = {
        .language = 10,
        .math = 20
    };
    /**** 运算符重载 ***/
    Grade *operator ->()
    {
        return &(this->grade);
    }
public: /* 不可重载运算符 */
    /************************************
    *下面是不可重载的运算符列表:
    *
    *   .:成员访问运算符
    *   .*, ->*:成员指针访问运算符
    *   :::域运算符
    *   sizeof:长度运算符
    *   ?::条件运算符
    *   #: 预处理符号
    **************************************/
};

#endif // PEOPLE_H

People.cpp

#include "people.h"

People::People(string name, string sex, int age)
    :m_name(name),m_sex(sex),m_age(age)
{

}

void People::Print()    /*打印参数信息*/
{
    cout << "\t姓名:" << m_name
         << "\t性别:" << m_sex
         << "\t年龄:" << m_age
         << endl;
}

main.cpp

#include 
#include "people.h"
using namespace std;

int main()
{
    /*** 双目运算符之四则运算 ***/
    People people1("张三","男",18);
    People people2("李四","女",19);

    /*** 调用四则运算 ***/
    People people3;
    people3 = people1 + people2;
    people3 = people1 - people2;
    people3 = people1 * people2;
    people3 = people1 / people2;
    people3 = people1 % people2;

    /*** 调用四则高阶运算 ***/
    people3 = people1 + 10;
    people3 = people1 + string("老师");  /* 过度 */

    /*** 调用赋值运算符 ****/
    people3 = people1;   /*本质:people3.operator =(people1); */
    people3 += people1;  /*本质:people3.operator +=(people1);*/
    people3 -= people1;
    people3 *= people1;
    people3 /= people1;
    people3 %= people1;

    people3 = "王老师";
    people3 = 58;

    people3.Print();
    people1.Print();
    /*** 调用逻辑运算符 ****/
    cout << "people3和people3是否相等:" << (people3 == people3 ? "==" : "!=") << endl;
    cout << "people3和people1是否相等:" << (people3 == people1 ? "==" : "!=") << endl;
    cout << "people3和people1是否相等:" << (people3 != people1 ? "!=" : "==") << endl;

    /*** 调用高阶逻辑运算符 ****/
    cout << "people3和 老师 是否相等:" << (people3 == "王老师" ? "==" : "!=") << endl;

    /*** 单目运算符: ++,-- ***/
#if 0
    int value = 10;


    /**** 前置 ****自己 和 返回值都是 自增1*/
//    cout << "++value = " << ++(++value) << endl;
//    cout << "value = " << value << endl;

    /**** 后置 ****返回当前,自己自增 1*/
    cout << "value++ = " << (value++)++ << endl;
    cout << "value = " << value << endl;
#else
    People people4("张三","男",16);
    /**** 前置 ****/
//    cout << (--(--(--people4))).m_age << endl;;
//    people4.Print();
    /**** 后置 ****/
    cout << (people4++).m_age << endl;;
    cout <<(people4).m_age << endl;;
#endif

    /*** 单目运算符: << , >> , & , | ^ ***/
#if 0
    int value = 1;  /* 0x01  ==== 0000 0011*/
    cout << "value << 1 = " << (value << 1) << endl;
    cout << "value = " << value << endl;
#else
    People people5("张三","男",1); /* 0x01  ==== 0000 0100*/
    cout << "(people5 >> 2).m_age = " << (people5 >> 2).m_age << endl;
    cout << "people5.m_age = " << people5.m_age << endl;

    cout << "(people5 & 0).m_age = " << (people5 & 0).m_age << endl;
    cout << "people5.m_age = " << people5.m_age << endl;

    /**** 高阶 << 运算符 ****/
    //cin >> people5;  输入
    cout << people5 << endl;;  //输出
#endif

    People people;
    people();   /* 调用仿函数 */
    cout << "是否相等:" << (people(10,20) == true ? "相等" : "不相等") << endl;

    people[3] = 5; /* 相当于 people.addr[3] = 5 ,解读当前想要操作的是int addr[3]*/
    cout << "people[3] = " << people[3] << endl;

    for(int i = 0; i < people["max"];i++)
    {
        cout << people[i] << ",";
    }
    cout << endl;
    /**** 去操作其他类的直接操作 ->  ***/
    people->language = 100;
    cout << "语文成绩:" << people->language << endl;
    return 0;
}

4.继承

People.h

#ifndef PEOPLE_H
#define PEOPLE_H
#include 
#include 
using namespace std;

/** 封装是隐藏实现 **/
class People
{
public:
    People(string name = "",string sex = "女",int age = 0);

public:
    string name() const;
    void setName(const string &name);

    string sex() const;
    void setSex(const string &sex);

    int age() const;
    void setAge(int age);

protected:
    string m_name;  /*姓名*/
    string m_sex;   /*性别*/
    int m_age;      /*年龄*/
};

#endif // PEOPLE_H

People.cpp

#include "people.h"

People::People(string name,string sex,int age)
    :m_name(name),m_sex(sex),m_age(age)
{

}

string People::name() const
{
    return m_name;
}

void People::setName(const string &name)
{
    m_name = name;
}

string People::sex() const
{
    return m_sex;
}

void People::setSex(const string &sex)
{
    m_sex = sex;
}

int People::age() const
{
    return m_age;
}

void People::setAge(int age)
{
    m_age = age;
}

Student.h

#ifndef STUDENT_H
#define STUDENT_H
#include "people.h"

class Grade
{
public:
    float language; /*语文*/
    float math;     /*数学*/
    float english;  /*英语*/
};

class Student : public People
{
public:
    Student(string id = "0",string name = "",string sex = "女",int age = 0);
    Student(string id ,float language,float math,float english,string name = "",string sex = "女",int age = 0);
    Student(string id ,Grade grade = {0,0,0},string name = "",string sex = "女",int age = 0);

    /**** 自己实现成员访问运算符 ****/
    Grade *operator ->()
    {
        return &(this->m_grade);
    }

    string ID() const;

protected:
    string m_ID;
    Grade m_grade;
};

#endif // STUDENT_H

Student.cpp

#include "student.h"

Student::Student(string id, string name, string sex, int age)
    //:m_ID(id),People(name,sex,age),m_grade{0,0,0}
    :Student(id,0,0,0,name,sex,age) /*构造函数相互调用*/
{

}

Student::Student(string id, float language, float math, float english, string name, string sex, int age)
    :m_ID(id),People(name,sex,age),m_grade{language,math,english}
{

}

Student::Student(string id, Grade grade, string name, string sex, int age)
    :Student(id,grade.language,grade.math,grade.english,name,sex,age) /*构造函数相互调用*/
{

}

string Student::ID() const
{
    return m_ID;
}

Teacher.h

#ifndef TEACHER_H
#define TEACHER_H
#include "people.h"

class Teacher : public People
{
public:
    Teacher(string id = "0",string name = "",string sex = "女",int age = 0);

    string ID() const;  /*获取工号*/
protected:
    string m_ID;/*工号*/
};

#endif // TEACHER_H

Teachar.cpp

#include "teacher.h"

Teacher::Teacher(string id, string name, string sex, int age)
    :m_ID(id),People(name,sex,age)
{

}

string Teacher::ID() const
{
    return m_ID;
}

main.cpp

#include 
#include "student.h"
#include "teacher.h"
using namespace std;

int main()
{
    Student stu("10000","王老师","男",18);
    Student stu1("10001",10,20,30,"李白","男",650);
    Student xxx;

    cout << stu1->english << endl;
    cout << stu1->language << endl;
    cout << stu1->math << endl;

    Teacher teacher("10000","李老师","女",16);
    cout << teacher.name() << endl;
    cout << teacher.ID() << endl;

    return 0;
}

/****** 案例 *******
 *       人类
 * 学生类  和  老师类
 * ****************/

你可能感兴趣的:(C++,语言的学习,c++,学习,开发语言)