• C++ 语言学习 day10 复习(1)


    1.
    /********* 探讨权限 ************
     * 权限|位置    类外  类内  派生
     * 公有:       √     √    √
     * 保护:       ×     √    √
     * 私有:       ×     √    ×

     * 总结:
     *      类外:只能访问公有成员
     *      类内:可访问所有成员
     *      派生:无法访问祖先类的私有成员
     *
     * 注意:
     *      C++中权限关键字开始位置就是权限
     *      直到下一个权限关键字或者类结束
     * ****************************/

    ******************************************************
     * 什么时候使用相关权限?
     * 公有:一般想让外界直接访问的之后使用公有权限,类似接口函数
     * 保护:既不想要外部访问,但是又想让派生类继承使用则使用保护权限
     * 私有:只允许内部自己访问,派生无法访问
     * ******************************************************/
     


    2.


    /********* 构造函数 和 析构函数 ***************
     *构造函数:
     *  作用:用于申请空间时初始化处理
     *  定义:
     *      1.函数名与类名相同
     *      2.无返回值
     *      --->通过从上定义规则可以发现,构造函数可以拥有参数,则可实现重载
     *析构函数:
     *  作用:用于销毁时做释放处理
     *  定义:
     *      1.函数名与类名相同,但多了一个~号
     *      2.无参,无返回值
     *      --->然通过以上定义规则发现,析构函数无法重载
     * 注意:
     *  如果用户没有提供构造和析构以及拷贝等函数则编译器默认提供
     *  1.无参构造
     *  2.拷贝构造(浅)
     *  3.析构函数
     *  4.=运算符函数
     * ******************************************/

    代码:

    1. #include <iostream>
    2. #include <string>
    3. using namespace std;
    4. /********* 构造函数 和 析构函数 ***************
    5. *构造函数:
    6. * 作用:用于申请空间时初始化处理
    7. * 定义:
    8. * 1.函数名与类名相同
    9. * 2.无返回值
    10. * --->通过从上定义规则可以发现,构造函数可以拥有参数,则可实现重载
    11. *析构函数:
    12. * 作用:用于销毁时做释放处理
    13. * 定义:
    14. * 1.函数名与类名相同,但多了一个~号
    15. * 2.无参,无返回值
    16. * --->然通过以上定义规则发现,析构函数无法重载
    17. * 注意:
    18. * 如果用户没有提供构造和析构以及拷贝等函数则编译器默认提供
    19. * 1.无参构造
    20. * 2.拷贝构造(浅)
    21. * 3.析构函数
    22. * 4.=运算符函数
    23. * ******************************************/
    24. class People
    25. {
    26. public:
    27. People(); /*无参构造*/
    28. People(string name,int age,string sex = "女"); /*带参构造*/
    29. People(const People &people); /*拷贝构造*/
    30. ~People(); /*析构函数*/
    31. public:
    32. void Print() const;/*接口函数*/
    33. void operator =(const People &people) /*=号赋值运算符*/
    34. {
    35. this->m_name = people.m_name;
    36. this->m_age = people.m_age;
    37. this->m_sex = people.m_sex;
    38. cout << "=号赋值运算符" << endl;
    39. }
    40. protected:
    41. string m_name; /*姓名*/
    42. int m_age; /*年龄*/
    43. string m_sex; /*性别*/
    44. };
    45. /***** 类外实现 *****/
    46. People::People() /*无参构造*/
    47. {
    48. this->m_name = "";
    49. this->m_age = 0;
    50. this->m_sex = "女";
    51. cout << "无参构造" << endl;
    52. }
    53. People::People(string name,int age,string sex)/*带参构造*/
    54. {
    55. this->m_name = name;
    56. this->m_age = age;
    57. this->m_sex = sex;
    58. cout << "带参构造" << endl;
    59. }
    60. People::People(const People &people) /*拷贝构造*/
    61. {
    62. this->m_name = people.m_name;
    63. this->m_age = people.m_age;
    64. this->m_sex = people.m_sex;
    65. cout << "拷贝构造" << endl;
    66. }
    67. People::~People() /*析构函数*/
    68. {
    69. cout << "析构函数" << endl;
    70. }
    71. void People::Print() const
    72. {
    73. cout << "\t姓名:" << this->m_name
    74. << "\t年龄:" << this->m_age
    75. << "\t性别:" << this->m_sex
    76. << endl;
    77. }
    78. int main()
    79. {
    80. /*1.实例化对象*/
    81. People people1; /* 默认调用无参 */
    82. People people2("张三",18,"男"); /*带参构造*/
    83. People people3("李四",17); /*带参构造*/
    84. People people4(people2); /*拷贝构造*/
    85. People people5 = people2; /*拷贝构造*/
    86. people5 = people3; /*=号赋值运算符*/
    87. /********* 输出结果内容 **********/
    88. cout << "\npeople1:" << endl;
    89. people1.Print();
    90. cout << "\npeople2:" << endl;
    91. people2.Print();
    92. cout << "\npeople3:" << endl;
    93. people3.Print();
    94. cout << "\npeople4:" << endl;
    95. people4.Print();
    96. cout << "\npeople5:" << endl;
    97. people5.Print();
    98. return 0;
    99. }


    3.
    /*********** 浅拷贝 Vs 深拷贝 *************************
     *浅拷贝: 是值拷贝,针对指针变量,则都是指向到同一片内存空间地址
     *      会造成:①一个操作多个对象 ②多次析构照成程序崩溃
     *深拷贝: 在堆区申请空间的操作都要实现
     *      注意:一般牵扯指针操作,都会自己实现深拷贝
     ****************************************************/

    代码:

    1. #include <iostream>
    2. #include <string>
    3. using namespace std;
    4. /*********** 浅拷贝 Vs 深拷贝 *************************
    5. *浅拷贝: 是值拷贝,针对指针变量,则都是指向到同一片内存空间地址
    6. * 会造成:①一个操作多个对象 ②多次析构照成程序崩溃
    7. *深拷贝: 在堆区申请空间的操作都要实现
    8. * 注意:一般牵扯指针操作,都会自己实现深拷贝
    9. ****************************************************/
    10. class A{
    11. public:
    12. A(){cout << "A的构造函数" <<endl;}
    13. ~A(){cout << "A的析构函数" <<endl;}
    14. string name[1000];
    15. };
    16. class People
    17. {
    18. public:
    19. People()
    20. {
    21. a = new A; /*申请*/
    22. }
    23. /******** 深拷贝 ********/
    24. People(const People &people)
    25. {
    26. /*** 重新申请空间,并修改指向 ***/
    27. this->a = new A; /*申请空间,修改指向*/
    28. *this->a = *people.a;/*拷贝内容到新的空间*/
    29. cout << "深拷贝构造函数" << endl;
    30. }
    31. ~People()
    32. {
    33. delete a; /*释放*/
    34. }
    35. public:
    36. A *a; /* 类成员指针 */
    37. };
    38. int main()
    39. {
    40. /***** 打印大小 *****/
    41. cout << "sizeof(string) = " << sizeof(string) << endl;
    42. cout << "sizeof(A) = " << sizeof(A) << endl;
    43. cout << "sizeof(People) = " << sizeof(People) << endl;
    44. /***** 1.实例化对象 ****/
    45. People *people = new People;
    46. people->a->name[0] = "张三";
    47. People people1(*people); /* 拷贝构造 */
    48. people1.a->name[0] = "李四";
    49. cout << "people->a->name[0]" << people->a->name[0] << endl;
    50. cout << "people1.a->name[0]" << people1.a->name[0] << endl;
    51. delete people;
    52. return 0;
    53. }

    4.

    /****** 程序的执行顺序(初始化顺序) **************
     * 1.自上而下
     * 2.从左往右
     * 总结:初始化列表不会影响正常初始化顺序
     * 总结:析构顺序与初始化顺序相反
     * *****************************************/

    代码:

    other.h

    1. #ifndef OTHER_H
    2. #define OTHER_H
    3. #include <iostream>
    4. using namespace std;
    5. class A{
    6. public:
    7. A(){cout << __func__<< endl;}
    8. A(int xx){cout << __func__<< endl;}
    9. ~A(){cout << __func__<< endl;}
    10. };
    11. class B{
    12. public:
    13. B(){cout << __func__<< endl;}
    14. B(int xx){cout << __func__<< endl;}
    15. ~B(){cout << __func__<< endl;}
    16. };
    17. class C{
    18. public:
    19. C(){cout << __func__<< endl;}
    20. ~C(){cout << __func__<< endl;}
    21. };
    22. class D{
    23. public:
    24. D(){cout << __func__<< endl;}
    25. ~D(){cout << __func__<< endl;}
    26. };
    27. /**** 人类中包含A和B *****/
    28. class People : public C,public D{
    29. public:
    30. People()
    31. :b(20),a(10)/*初始化列表 父类构造 -> 成员*/
    32. {cout << __func__<< endl;}
    33. ~People(){cout << __func__<< endl;}
    34. public:
    35. A a;
    36. B b;
    37. };
    38. class Student
    39. {
    40. public:
    41. Student(string name,int age)
    42. :m_name(name),m_age(age)
    43. {
    44. }
    45. public:
    46. string m_name;
    47. int m_age;
    48. };
    49. #endif // OTHER_H

    main.c

    1. #include <iostream>
    2. #include "Other.h"
    3. using namespace std;
    4. /****** 程序的执行顺序(初始化顺序) **************
    5. * 1.自上而下
    6. * 2.从左往右
    7. * 总结:初始化列表不会影响正常初始化顺序
    8. * 总结:析构顺序与初始化顺序相反
    9. * *****************************************/
    10. int main()
    11. {
    12. /*1.实例化People */
    13. People people; // C -> D -> A -> B -> People
    14. Student stu("张三",18);
    15. cout << stu.m_name << "\t" << stu.m_age << endl;
    16. return 0;
    17. }/* 调用析构: ~People -> ~B -> ~A -> ~D -> ~C */

    5.

    /******** 常量成员 ***************************************
     * 通过前面的铺垫,我们初始化列表专门给常量成员做初始化操作
     * 分类:
     *      常量成员属性:
     *          定义:在变量名之前加 const
     *          作用:只初始化赋值一次,以后无法更改,必须由 "初始化列表" 操作
     *      常量成员函数:
     *          定义:在函数参数后加 const
     *          作用:该函数不可修改类成员属性值,只可访问
     *              自己在函数中定义的变量可以修改
     *          注意:一般读取函数都会写成const常函数
     *
     *      常对象只能访问常函数,后面set容器存放的都会变成常对象
     * *****************************************************/

    代码:

    1. #include <iostream>
    2. using namespace std;
    3. /******** 常量成员 ***************************************
    4. * 通过前面的铺垫,我们初始化列表专门给常量成员做初始化操作
    5. * 分类:
    6. * 常量成员属性:
    7. * 定义:在变量名之前加 const
    8. * 作用:只初始化赋值一次,以后无法更改,必须由 "初始化列表" 操作
    9. * 常量成员函数:
    10. * 定义:在函数参数后加 const
    11. * 作用:该函数不可修改类成员属性值,只可访问
    12. * 自己在函数中定义的变量可以修改
    13. * 注意:一般读取函数都会写成const常函数
    14. *
    15. * 常对象只能访问常函数,后面set容器存放的都会变成常对象
    16. * *****************************************************/
    17. class People
    18. {
    19. public:
    20. People():value(10)
    21. {
    22. }
    23. public:
    24. /**** 成员属性 ****/
    25. const int value;
    26. int m_temp;
    27. public:
    28. /**** 成员函数 ****/
    29. void Print() const
    30. {
    31. /* 访问 */
    32. cout << "value = " << value << endl;
    33. cout << "m_temp = " << m_temp << endl;
    34. /* 修改 */
    35. //m_temp = 500;
    36. /* 自定义函数变量可修改 */
    37. int xxx = 10;
    38. xxx = 50;
    39. }
    40. void SetTemp(int temp)
    41. {
    42. m_temp = temp;
    43. }
    44. int temp() const;
    45. };
    46. int main()
    47. {
    48. People people;
    49. people.Print(); /* 调用 const 成员函数 */
    50. people.SetTemp(50);/* 调用 非const 成员函数 */
    51. const People peo;
    52. peo.Print();/* 调用 const 成员函数 */
    53. //peo.SetTemp(50);/* 调用 非const 成员函数 */ 报错: 常对象只能调用常函数
    54. return 0;
    55. }
    56. int People::temp() const
    57. {
    58. return m_temp;
    59. }


    6.

    /********** this 指针和空指针 *********
     * 都是指向到自己的指针
     * *********************************/

    代码:

    1. #include <iostream>
    2. using namespace std;
    3. class People
    4. {
    5. public:
    6. People(string name = "wu",int age = 0) : m_name(name),m_age(age){} /* 构造函数 */
    7. void Print();
    8. void SetValue(int value);
    9. public:
    10. string m_name;
    11. int m_age;
    12. int value; /*注意这个成员*/
    13. };
    14. /********** this 指针和空指针 *********
    15. * 都是指向到自己的指针
    16. * *********************************/
    17. void People::Print()
    18. {
    19. /**** this指针案例 ****/
    20. cout << "name = " << this->m_name << endl;
    21. printf("this = %p\n",this);
    22. /**** 空指针案例 : 会造成同名问题,所以使用this指针解决*****/
    23. cout << "name = " << m_name << endl;
    24. cout << "value = " << value << endl;
    25. }
    26. /** 发现类成员属性名与函数参数名重名 **/
    27. /** 根据调用优先级规则,谁定义得近调用谁**/
    28. void People::SetValue(int value)
    29. {
    30. /** 在这里设置会不产生任何效果:因为 value是栈自己定义的会随着销毁 **/
    31. value = value;
    32. /** 可以 使用this指针解决该问题 **/
    33. this->value = value;
    34. }
    35. int main()
    36. {
    37. People people;
    38. people.SetValue(500);
    39. people.Print();
    40. People *ptr = &people;
    41. printf("ptr = %p\n",ptr);
    42. return 0;
    43. }

    7.

    /********  静态成员特征 *********
     * 公有特征:
     *      1.可以通过对象 或 类名访问
     *      2.所有对象公用同一静态变量空间
     *
     * 静态成员属性:
     *      注意:类内声明,类外初始化
     *      常用:用作数据记录
     *      须知:
     *          1.所有对象共享同一份数据
     *          2.空间在编译阶段就已经分配
     *          3.静态成员不占用对象空间
     * 静态成员函数:类内声明类外实现也可以,类内实现也可以
     *      注意:静态成员函数不能使用非静态成员,所以也不能访问this指针
     *      常用:接口处理(数据集,固定参数"串口参数,摄像头参数,音频参数,网络参数等")
     *
     * ***************************/

    代码:

    1. #include <iostream>
    2. #include <string>
    3. using namespace std;
    4. class People
    5. {
    6. public:
    7. People(){
    8. s_value++;
    9. }
    10. public: /* 成员函数 */
    11. static void GetValue() /* 静态成员函数 */
    12. {
    13. cout << "我是静态成员函数" << endl;
    14. cout << "s_value = " << s_value << endl;
    15. //cout << "m_value = " << m_value << endl; 报错:静态成员函数不能使用非静态成员
    16. }
    17. static string GetIP()
    18. {
    19. return "IPV4 192.168.1.100";
    20. }
    21. static int GetMax(int value1,int value2)
    22. {
    23. return value1 > value2 ? value1 : value2;
    24. }
    25. public: /* 成员属性 */
    26. static int s_value; /*静态成员属性:类内声明,类外初始化*/
    27. int m_value;
    28. };
    29. /******** 静态成员特征 *********
    30. * 公有特征:
    31. * 1.可以通过对象 或 类名访问
    32. * 2.所有对象公用同一静态变量空间
    33. *
    34. * 静态成员属性:
    35. * 注意:类内声明,类外初始化
    36. * 常用:用作数据记录
    37. * 须知:
    38. * 1.所有对象共享同一份数据
    39. * 2.空间在编译阶段就已经分配
    40. * 3.静态成员不占用对象空间
    41. * 静态成员函数:类内声明类外实现也可以,类内实现也可以
    42. * 注意:静态成员函数不能使用非静态成员,所以也不能访问this指针
    43. * 常用:接口处理(数据集,固定参数"串口参数,摄像头参数,音频参数,网络参数等")
    44. *
    45. * ***************************/
    46. /** 静态成员属性类外初始化 **/
    47. int People::s_value = 0;
    48. int main()
    49. {
    50. /* 1.实例化对象 */
    51. //People people;
    52. /* 2.调用对象 */
    53. /* 2.1 实例对象调用静态成员 */
    54. //cout << people.s_value << endl;
    55. /* 2.2 通过类名调用静态成员 */
    56. //cout << People::s_value << endl;
    57. //People::GetValue();
    58. /* 2.3 通常静态成员属性做记录数据 */
    59. //cout << "当前女娲造人:" << People::s_value << endl;
    60. //{People people;}
    61. //cout << "当前女娲造人:" << People::s_value << endl;
    62. //{People people;}
    63. //cout << "当前女娲造人:" << People::s_value << endl;
    64. //{People people;}
    65. //cout << "当前女娲造人:" << People::s_value << endl;
    66. //{People people;}
    67. //cout << "当前女娲造人:" << People::s_value << endl;
    68. /* 2.4 通常静态函数做接口使用 */
    69. cout << People::GetIP() << endl;
    70. cout << People::GetMax(10,20) << endl;
    71. /* 2.5 静态成员不占用类空间 */
    72. cout << "sizeof(People) = " << sizeof(People) << endl;
    73. /* 3.销毁对象 */
    74. return 0;
    75. }

  • 相关阅读:
    英文ppt怎么翻译成中文?教你几种ppt翻译方法
    李峋同款爱心代码!跳动的心,给你爱的人一个惊喜!
    MySQL基本操作之数据库设计理论
    Vue 显示关键词附近内容并高亮显示关键词
    羧甲基壳聚糖-丙硫菌唑水凝胶微球/壳聚糖/磷酸甘油盐温敏性水凝胶/石墨烯壳聚糖复合水凝胶
    APIAuto——敏捷开发最强大易用的 HTTP 接口工具 (二)
    LeetCode537
    前端工程化:保姆级教学 Jenkins 部署前端项目
    kafka本地安装报错
    人声分离网站,帮你快速提取视频中的人声和背景音乐
  • 原文地址:https://blog.csdn.net/she666666/article/details/127988702