• c++ 语言学习 day03 (QT 知识编译工具变了) 友元(函数和类) ,类的静态成员 ,const成员,运算符重载:,this


    一、友元(函数和类)
        1.友元函数:在类内申明,在类外定义,不属于当前类,但可以访问当前类的所有成员变量和成 员 方法(包含私有共有和保护)



        2.定义: friend 返回值 函数名(类的对象)
                  在函数前加friend。



        3.调用:不可以通过成员.函数名() 的方式调用,因为不是成员函数。
                  当做全局函数使用,直接函数名加参数的方式使用;
       



         4.注意:申明在类内,加上friend,一般情况下需要传入当前类的对象
                   可以在类内实现,也可以在类外实现,类外实现不需要加friend关键字
      



        5.友元类:把另外一个类放入当前类,则另外一个类可以访问我的所有成员变量和成员函数。
        格式: class test { friend class 类名; }



        6.注意:友元类不是相互的,当a是b的友元时,a可以通过b的对象访问b中的所有成员函数和变量,包含私有。但b不可以访问a的私有和包含成员变量。


    代码:

    头文件:

    1. #ifndef FRIEND_H
    2. #define FRIEND_H
    3. class stu
    4. {
    5. private:
    6. int age;
    7. public:
    8. friend void print(stu &dd);//友元函数
    9. stu(int k1);//有参构造
    10. stu();//无参构造
    11. ~stu();//析构函数
    12. };
    13. #endif // FRIEND_H

    .cpp文件:

    1. #include <iostream>
    2. #include"friend.h"
    3. using namespace std;
    4. void print(stu &dd)
    5. {
    6. cout<<"age: "<<dd.age<<endl;
    7. }
    8. stu::stu(int k1)
    9. {
    10. age=k1;
    11. }
    12. stu::stu()
    13. {
    14. age=10;
    15. }
    16. stu::~stu()
    17. {
    18. cout<<"析构了"<<endl;
    19. }
    20. int main()
    21. {
    22. stu danny(100);
    23. stu danny1;
    24. print(danny);
    25. print(danny1);
    26. return 0;
    27. }


    二、类的静态成员
          分为类的静态成员函数和类的静态成员变量



          2.1静态成员变量:
              格式:static 类型 变量;
              注意:静态成员变量直接属于类,不属于对象。只有一份。所有对象公用一份,如果通过某一个对象修改静态成员变量,所有对象都修改。



           2.2 静态成员变量初始化
                 初始化在类外,使用  类型 类名::变量名 = 值的方式进行初始化 
                 例如: class Box{public:    static double lenght;}



           2.3使用
                    类名::静态变量名= 值;
                    对象.静态变量名 = 值;(不属于对象)



           2.4静态成员函数
                格式: static 返回值 函数名(参数列表){}
                 注意:静态成员函数在没有对象的时候也可以访问,直接使用类名::函数名的方式,不一定要对象.静态成员函数 的形式
                            静态成员函数智能访问静态成员数据、其他静态成员函数和类外的其他函数,不可以访问非静态成员变量
                            可以使用静态成员函数来判断类的其他对象是否创建。
                            静态成员函数中无this指针,所以不可以访问普通成员变量。     
                           如果声明和实现分开,在实现函数时不需要加static


    代码:

    头文件:

    1. #ifndef POINTER_H
    2. #define POINTER_H
    3. #include
    4. using namespace std;
    5. class pointer
    6. {
    7. private:
    8. double lenght;
    9. double width;
    10. double heighr;
    11. public:
    12. static int num;//静态成员变量需要在类内声明,类外初始化
    13. pointer();
    14. ~pointer();
    15. pointer(double a,double b,double c);
    16. static void show();//静态函数 只能调用类里面的静态变量 , 不能调用其他成员
    17. };
    18. #endif // POINTER_H

    .cpp 文件

    1. #include "pointer.h"
    2. pointer::pointer()
    3. {
    4. num++;
    5. lenght=0;
    6. width=0;
    7. heighr=0;
    8. }
    9. pointer::~pointer()
    10. {
    11. }
    12. pointer::pointer(double a,double b,double c)
    13. {
    14. num++;
    15. lenght=a;
    16. width=b;
    17. heighr=c;
    18. }
    19. int pointer::num=0;//静态成员变量需要在类内声明,类外初始化
    20. void pointer::show()
    21. {
    22. cout<<"lenght:"<<num<<endl;
    23. }
    24. int main()
    25. {
    26. pointer a;
    27. pointer b(1.1,2.2,3.3);
    28. a.show();
    29. b.show();
    30. return 0;
    31. }

    三、this
         初始化列表: 是在构造函数时候,对成员变量进行初始化使用
                  格式:在构造函数后加冒号,后加成员变量名(参数)的形式
                 例如:class box {  int a;int b;int c;     public: box(int a,int b,int c):a(a),b(b),c(c){  }      };
                 注意: 初始化列表在构造函数执行前执行,执行完后再执行大括号中内容。



                  this指针:在类中表示当前对象。理解成"我". 每个对象的我都表示自己。
                   每个对象都有一个特殊的指针,指向对象本身;
                   在每一个普通成员函数中,都默认传入了this指针,所以成员函数才能使用成员变量
                  而在普通成员函数中使用成员变量时,可以省略this。所以成员变量当成了普通变量使用。
          注意:静态成员函数没有this指针。友元函数也没有this指针。


    代码:

    头文件:

    1. #ifndef KK_H
    2. #define KK_H
    3. #include
    4. using namespace std;
    5. class kk
    6. {
    7. private:
    8. int a;
    9. int b;
    10. int c;
    11. public:
    12. kk();
    13. kk(int a,int b,int c);
    14. void print();
    15. void hh()const;
    16. };
    17. #endif // KK_H


    .cpp 文件

    1. #include "kk.h"
    2. kk::kk():a(0),b(0),c(0)//初始化,成员数据,在括号里面的程序运行之前//在初始化构造之前的时候 已经把数据给赋值了
    3. {
    4. }
    5. kk::kk(int a,int b,int c)
    6. {
    7. this->a=a;//this 指针指向自己的对象成员
    8. this->b=b;
    9. this->c=c;
    10. }
    11. void kk::print()
    12. {
    13. cout<<a<<" "<<b<<" "<<c<<endl;
    14. }
    15. void kk::hh()const//定义之前加了 const 所以成员不可以被改变
    16. {
    17. cout<<"a:"<<a<<endl;
    18. }
    19. int main()
    20. {
    21. kk dd;
    22. kk cc(1,2,3);
    23. dd.print();
    24. cc.print();
    25. return 0;
    26. }

    四、const成员
        分类:const成员变量  和 const成员函数
        const成员变量:
         特点:

    不允许修改
     必须在类内部初始化,可以在定义成员变量时赋值;
     可以在初始化列表中对const成员变量初始化。不可以在构造函数的大括号中直接赋值const变量



       const成员函数:
               定义:const关键字必须放在参数列表后,函数的声明和实现都必须带const属性



           注意: 在const成员函数中,不允许修改成员变量的值
                      const成员函数中,不可以调用非const的成员函数。
                      const的对象只可以调用const的成员函数,不可以调用非const成员函数
                      非const的对象可以调用const成员函数和非const成员函数
                      const成员函数和非const成员函数构成重载(重点)


    代码:

    头文件:

    1. #ifndef PERSON_H
    2. #define PERSON_H
    3. #include
    4. #include
    5. using namespace std;
    6. class person
    7. {
    8. private:
    9. int age;
    10. const string name = "abc";
    11. public:
    12. person();
    13. void grow();
    14. void show()const;
    15. };
    16. #endif // PERSON_H

    .cpp文件

    1. #include "person.h"
    2. person::person():age(0)
    3. {
    4. }
    5. void person::grow()
    6. {
    7. cout<<"age: "<<age<<" "<<"name :"<<name<<endl;
    8. }
    9. void person::show()const
    10. {
    11. cout<<"age: "<<age<<" "<<"name :"<<name<<endl;
    12. }
    13. int main()
    14. {
    15. person a;
    16. a.show();
    17. a.grow();
    18. return 0;
    19. }

    五、运算符重载:
          1. 重载:在相同作用域内函数名相同参数列表不同(const),返回值没关系。
           2.运算符重载:重新编写一个运算符,用来对多个对象进行操作,例如 student a;student b; a+b;
           3.格式:返回值  operator运算符(参数){   }
           4.运算符:
                        算数运算符: + - * / %
                        关系运算符:  >    <     >=   <=    ==    !=
                        逻辑运算符:    &&  ||    !
                        位运算符:   &     |    ^    >>    <<
                        自增自减: ++x    , x++ ,    --x   , x--;
                        赋值运算符:   = , +=   >>=   
                        单目运算符:   +(正号)     -(负号)      &(地址)
                       内存申请:  new  delete  sizeof
                         其他:   ( )       ->          ,        [ ]   ,  ?:
                      不可以重载的运算符:?:         . (点)   sizeof            ,   *(解引用运算符)     ::(域运算符)       #
     



           6.运算符重载的实现方式:
                   成员函数实现:在类内做运算符重载,一般情况下传入一个对象或者一个变量
                                          赋值运算符 =, 下标运算符[ ],   指针运算符,流运算符 >>
                   全局函数实现:在类外定义,一般情况下参数是两个对象(双目运算符)



           7.算数运算符:
                成员变量实现方式: int operator + (const person& other)  {      int x = this->age + other.age;     return x;   }
               友元函数实现方式: friend  person operator -(const person& me,const person& other){ return person(me.age+other.age);}
               全局函数实现方式: int operator -(const person& me,const person& other){return me.getAge()+other.getAge();}
               补充:匿名对象,没有变量名的对象,用完后立马析构,构建对象形式类似 调用构造函数;



           8.关系运算符重载
               成员变量实现方式: bool operator > (const person& other)  {     }
        


    代码:

    头文件

    1. #ifndef CHONGZAI1_H
    2. #define CHONGZAI1_H
    3. #include<iostream>
    4. #include<string>
    5. using namespace std;
    6. class chongzai1
    7. {
    8. private:
    9. int age;
    10. public:
    11. chongzai1(int age =2);
    12. void show();
    13. int get();
    14. void set(int age1);
    15. int get_age()const;
    16. chongzai1 operator+(const chongzai1& a);//重载 加法+
    17. //友元不是类的成员
    18. friend bool operator <=(const chongzai1 & me,const chongzai1 &other);//友元方式实现 <= 的运算符重载
    19. //重载 符号
    20. chongzai1 operator -();
    21. };
    22. chongzai1 operator -(chongzai1& me , chongzai1& other );//重载 运算符减号
    23. chongzai1 operator /(const chongzai1& me ,const chongzai1& other );//重载 运算符 除号
    24. chongzai1 operator *(const chongzai1& me ,const chongzai1& other );//重载 运算符 乘号
    25. chongzai1 operator --(chongzai1 & me,int);//重载 后减减
    26. chongzai1 operator ++(chongzai1 & me);//重载 前加加
    27. chongzai1 operator ++(chongzai1 & me,int);//重载 后加加
    28. chongzai1 operator --(chongzai1 & me);//重载 前减减
    29. #endif // CHONGZAI1_H

    .cpp 文件

    1. #include "chongzai1.h"
    2. chongzai1::chongzai1(int age)//默认值,实现的时候不用加
    3. {
    4. this->age=age;
    5. }
    6. void chongzai1::show()
    7. {
    8. cout<<"age:"<<age<<endl;
    9. }
    10. int chongzai1::get()
    11. {
    12. return age;
    13. }
    14. void chongzai1::set(int age1)
    15. {
    16. age=age1;
    17. }
    18. int chongzai1::get_age()const
    19. {
    20. return age;
    21. }
    22. chongzai1 chongzai1::operator +(const chongzai1& a)
    23. {
    24. chongzai1 x;
    25. x.age= a.age+this->age;
    26. return x;
    27. }
    28. chongzai1 operator -(chongzai1& me ,chongzai1& other )
    29. {
    30. int x = me.get()+other.get();
    31. return chongzai1(x);//临时对象 匿名对象
    32. }
    33. chongzai1 operator /(const chongzai1& me , const chongzai1& other )
    34. {
    35. int x = me.get_age()/other.get_age();
    36. return chongzai1(x);//临时对象 匿名对象
    37. }
    38. chongzai1 operator *(const chongzai1& me , const chongzai1& other )
    39. {
    40. int x = me.get_age()* other.get_age();
    41. return chongzai1(x);//临时对象 匿名对象
    42. }
    43. bool operator <=(const chongzai1 & me,const chongzai1 &other)
    44. {
    45. return me.get_age()<=other.get_age();
    46. }
    47. //后减减
    48. chongzai1 operator--( chongzai1 & me,int)
    49. {
    50. chongzai1 temp =me;
    51. int x=me.get()-1;
    52. me.set(x);
    53. return temp;
    54. }
    55. //前加加
    56. chongzai1 operator ++(chongzai1 & me)//前加加
    57. {
    58. int x=me.get()+1;
    59. me.set(x);
    60. return me;
    61. }
    62. chongzai1 operator ++(chongzai1 & me,int)//后加加
    63. {
    64. chongzai1 temp =me;
    65. int x=me.get_age()+1;
    66. me.set(x);
    67. return temp;
    68. }
    69. chongzai1 operator --(chongzai1 & me)//前减减
    70. {
    71. int x=me.get()-1;
    72. me.set(x);
    73. return me;
    74. }
    75. chongzai1 chongzai1::operator -()//重载 负号
    76. {
    77. return chongzai1(-age);
    78. }
    79. int main()
    80. {
    81. /*
    82. chongzai1 c=a+b;
    83. a.show();
    84. b.show();
    85. c.show();
    86. chongzai1 d =a/b;
    87. d.show();
    88. chongzai1 dd=a*b;
    89. dd.show();
    90. cout.setf(ios_base::boolalpha);//bool 类型输出 ture 和 false 不是输出 1 或者 0
    91. bool jj=b<=a;
    92. cout<<jj<<endl;
    93. */
    94. --b;
    95. b.show();
    96. ++a;
    97. a.show();
    98. chongzai1 c= b--;
    99. chongzai1 d= a++;
    100. b.show();
    101. c.show();
    102. a.show();
    103. d.show();
    104. d=-d;
    105. d.show();
    106. return 0;
    107. }

    >> 运算符号的重载 

    头文件
           

    1. #ifndef LIU_H
    2. #define LIU_H
    3. #include "liu.h"
    4. #include
    5. #include
    6. #include
    7. #include
    8. using namespace std;
    9. class liu
    10. {
    11. public:
    12. int id;
    13. string name, grade;
    14. liu(){};
    15. liu(int id, string name, string grade);
    16. bool operator < (const liu & s) const;
    17. };
    18. istream & operator >> (istream & in, liu & s);
    19. ostream & operator << (ostream & out, liu & s);
    20. #endif // LIU_H

       


    .cpp 文件

    1. #include "liu.h"
    2. #include <iostream>
    3. #include <vector>
    4. #include <string>
    5. #include <algorithm>
    6. using namespace std;
    7. bool liu ::operator < (const liu & s) const
    8. {
    9. return id<s.id;
    10. }
    11. istream & operator >> (istream & in, liu & s)
    12. {
    13. in >> s.id >> s.name >> s.grade;
    14. return in;
    15. }
    16. ostream & operator << (ostream & out, liu &s)
    17. {
    18. out << s.id << " " << s.name << " " << s.grade << endl;
    19. return out;
    20. }
    21. /*
    22. int main()
    23. {
    24. vector<Student> sv;
    25. liu temp;
    26. while (cin >> temp)
    27. {
    28. sv.push_back(temp);
    29. }
    30. sort(sv.begin(), sv.end());
    31. for (int i = 0; i < sv.size(); ++i)
    32. cout << sv[i];
    33. return 0;
    34. }
    35. */


  • 相关阅读:
    以太网协议介绍(ARP、UDP、ICMP、IP)
    frp远程运维技术
    RFID固定资产定位管理系统-智慧资产人员可视化管理系统
    Java系列 - 新版MybatisPlus代码生成
    JMeter之脚本录制
    当下,产业园区发展面临的十大问题
    Salesforce-Visualforce-1.概要(Get Started with Visualforce)
    spa之解决ajax跨域问题
    Servlet 学习笔记4
    【iOS】——用单例类封装网络请求
  • 原文地址:https://blog.csdn.net/she666666/article/details/126511359