C++ 开发【深入浅出】笔记01

  1. 应用场景:

    1. 高低级程序设计、嵌入式系统、数值计算方面、Adobe等
  2. 主要三方面内容:

    1. 封装:基础
    2. 继承:核心
    3. 多态:延展
  3. c++中如何表达: 

    1. int i;
    2. c:    定义一个变量         面向过程
    3. c++:实例化一个对象     面向对象
    4. c语言也可以实现c++思想
  4. c++定义变量:

    1. 也是根据个人风格的;逐渐养成
    2. 比如:int num; char name;
    3. int i_num;  char ch_name;等
  5. 读入、输出

    1. 读入流 cin >> val; 输出流 cout << val << endl;
    2. 错误流:cerr << "Error message : " << str << endl;

  6. 命名空间:namespace

    1. namespace NAME{
    2.       成员;
    3. }没有分号
    4. :: 域解析运算符
  7. 类:class

    1. class className
      {
      public:
          成员方法;(动态,函数或方法)
      private:    
          数据成员;(静态,数据或数值)

      };

    2. 一对 { } 是成员列表边界符,与成员列表一起成为类体。类体后面必须用 ; 结束。

    3. 关于类内成员
      1. 每个类可以没有成员,也可以有多个成员。

      2. 类成员可以是数据或函数。

      3. 所有成员必须在类内部声明,一旦类定义完成后,就没有任何其他方式可以再增加或减少成员。

    4. 三种访问权限:
      1. public:公有成员,类内类外均可访问

      2. protected:保护成员,在没有发生继承关系时,同private

      3. private:私有成员,只能类内访问,类外不可访问

      4. 如果在声明的时候不写访问控制属性,则类会默认它为private。

    5. 在面向对象程序设计中,一般将变量(数据成员)隐蔽起来,外部不能直接访问。把成员方法作为对外界的接口,通过成员方法访问数据解决c程序访问数据的安全性问题

    6. 定义类中成员方法的方式
      1. 在类内部定义:程序在要调用它的时候把它当作是一个内联函数,内联函数的好处是调用速度更快,但是会占用额外的内存空间,每调用一次都相当于定义一次,inline关键退化为建议型关键字,由编译器来决定是否将某函数作为内联

      2. 在类外部定义:可以是递归的函数

    7. 类的声明是否占用存储空间?
      1. 不占用存储空间

      2. 仅当实例化对象时,对象占用相对应的大小空间

    8. 访问对象中的成员有三种方法:

      通过对象名和对象成员引用运算符 (.) 

      通过指向对象的指针和指针成员引用运算符 (->)

      通过对象的引用变量和对象成员引用运算符 (.) 

    9. 最后一种访问方式:Test test, &r = test;    r.Sum();

  8. 练习01:

    1. 抽象一个长方体类,方法:1获取长宽高,2计算体积

  9. 动态指针对象

    1. Test *p = new Test;         delete p;           p = NULL;

    2. Test *p = new Test[3];    delete [ ] p;       p = NULL;

  10. 引用:

    1. 理解为某块空间/某个变量的别名,实际常常可以达到0开销

    2. 引用必须在定义时就指定引用的对象,且不可更改

    3. C中定义变量均可用:TYPE NAME = VALUE;   如:int a[3];  ->  int[3]  a;

    4. char类型的引用,本质上相当于 sizeof(char)

  11. 函数传参:(参数带默认值)

    1. 若用户进行传参,则以传参为准

    2. 若用户未进行相应参数传递,则使用默认值

    3. 从带默认值的形参往后的所有形参必须全部带默认值

    4. C++中对于特定的某个函数,设置默认形参这个动作只能有一次

  12. 类中的特殊函数:构造函数,拷贝构造函数,析构函数

    1. 构造函数:作用初始化某一个对象
      1. 在实例化一个对象时被自动隐式调用,且无须显示调用

      2. 我们若没有自行实现,则系统会为我们生成一个默认的构造函数,若我们自行实现了一个或多个构造函数,则系统默认的不会再生成

      3. 外形特点:构造函数名与类同名,可传参,可不传,无返回值,构造函数可存在一个或多个

      4. 构造函数可重载,参数可以有默认值

      5. #include <iostream>
         
        using namespace std;
         
        class Test
        {
        public:
            Test() {}
            Test(int x,int y):a(x),b(y) {}
            void Sum();
        private:
            int a,b;
        };
         
        void Test::Sum()
        {
            cout<<a+b;
        }
        class AnotherTest
        {
        public:
            AnotherTest(int i,int j):test(i,j) {test.Sum();}
        private:
            Test test;
        };
        int main()
        {
            AnotherTest test(3,4);
            return 0;
        }
        
        Test(int x = 0,int y):a(x),b(y) {} //这样是错误的。
        
        
    2. 析构函数:作用是清理和释放
      1. 在一个对象即将消亡的时候被自动的隐式调用,通常调用顺序与构造逆序
      2. 我们若没有自行实现,则系统会为我们生成一个默认的析构函数,一旦我们自行实现,则不会再有系统默认的生成
      3. 外形特点:析构函数与类同名,前面加个~,析构函数只能有一个,无传参,无返回值
      4. 析构函数何时被调用?
        1. 生命周期结束 (在栈区创建的对象,生命周期结束时,会自动执行析构函数)
        2. delete (用new创建的对象,函数返回时,不会自动执行析构函数,需要手动delete才能执行析构函数。注意:不主动delete,容易造成内存泄漏)
        3. 包含关系 (当对象1的private里有对象2时,当对象1析构后,对象2会自动析构)
        4. 继承关系 (栈区子对象生命周期结束时,会先执行自身析构函数,再执行对象的析构函数)
        5. new调用构造函数、delete调用析构函数
        6. 引荐实现代码
          https://blog.csdn.net/Dontla/article/details/126659030?app_version=6.2.1&code=app_1562916241&csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22126659030%22%2C%22source%22%3A%22weixin_51984896%22%7D&uLinkId=usr1mkqgl919blen&utm_source=app
    3. 拷贝构造函数:作用初始化某一个对象
      1. 在实例化一个对象时,用相同类型的已有对象给新对象初始化,这时调用拷贝构造函数而不是构造函数
      2. 外形特点:函数名与类名相同,传参为一个常引用,无返回值
      3. 若我们没有自行实现,则系统会生成一个默认的,如自行实现,默认的不再生成
    4. 定义一个类至少有几个方法?默认构造方法、默认的拷贝构造方法、析构方法
  13. 练习02:

    1. 构建一个Person类,私有数据成员为姓名(char*)+年龄(int)+ 常量性别,公有方法:构造,析构,拷贝构造,赋值,打印,改名。

  14. 浅拷贝与深拷贝:通俗点说

    1. 浅拷贝:默认生成的拷贝构造函数就是此种方式,相应的成员之间直接完成了赋值操作,包括动态分配的空间(即指针成员)

    2. 深拷贝:拷贝类中的成员时,将成员所对应的动态存储空间也另外开辟一份,各自使用各自的

    3. 什么时候需要深拷贝? 类中有指针成员变量的时候

    4. 类中有指针,并动态开辟,一定要显示定义拷贝构造方法

  15. this指针:

    1. 在类中的特殊函数中,this指针被当作默认的隐藏的传参,this指针指向当前调用该方法的对象

  16. 初始化列表:作用初始化类中的成员

    1. 构造方法函数声明后的位置叫做初始化列表位置

    2. 适用情况:类中有引用成员变量,const成员,对象成员

  17. 练习03:

  18. 类的静态数据成员及静态成员方法

    1. 静态数据成员:通常是用于统计或计数,它不从属于任何一个对象,存储空间只有一份,只是类中的一个成员。在类中仅作声明,类外初始化,通常需要初始化为0,并且在类内可直接访问,类外,通常<类名>::<静态成员名>,也可只是静态成员名

    2. 静态成员变量是在程序编译时分配空间,而在程序结束时释放空间

    3. 不能用参数初始化表,对静态成员变量进行初始化

    4. 既可以通过类名来对静态成员变量进行引用,也可以通过对象名来对静态成员变量进行引用。[私有除外]

    5. 静态成员方法访问类中的静态数据成员,没有this指针参与,不能访问类中的普通数据成员。<类名>::<静态成员方法名()>

    6. 不能通过类名来调用类的非静态成员方法

    7. 类的对象可以使用静态成员方法和非静态成员方法。

    8. 静态成员方法中不能引用非静态成员。

    9. 类的非静态成员方法可以调用静态成员方法,但反之不能。

    10. 类的静态成员变量必须先初始化再使用

    11. 静态数据成员是所有类对象所共有的

    12. https://blog.csdn.net/Chroniccandy/article/details/108621102
  19. 友元函数、友元类

    1. 你要使用我私有的东西,我就需要提前声明你是我的朋友,打破c++封装概念

    2. 友元函数是单向的、友元函数不可继承、友元函数没有this指针

    3. https://zhuanlan.zhihu.com/p/158805900#:~:text=%E5%8F%8B%E5%85%83%E5%8F%AF%E4%BB%A5%E6%98%AF%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%EF%BC%8C%E4%B9%9F%E5%8F%AF%E4%BB%A5%E6%98%AF%E4%B8%80%E4%B8%AA%E7%B1%BB%EF%BC%8C%E8%AF%A5%E7%B1%BB%E8%A2%AB%E7%A7%B0%E4%B8%BA%E5%8F%8B%E5%85%83%E7%B1%BB%E3%80%82,%E5%8F%8B%E5%85%83%E7%B1%BB%E7%9A%84%E6%89%80%E6%9C%89%E6%88%90%E5%91%98%E5%87%BD%E6%95%B0%E9%83%BD%E6%98%AF%E5%8F%A6%E4%B8%80%E4%B8%AA%E7%B1%BB%E7%9A%84%E5%8F%8B%E5%85%83%E5%87%BD%E6%95%B0%EF%BC%8C%E9%83%BD%E5%8F%AF%E4%BB%A5%E8%AE%BF%E9%97%AE%E5%8F%A6%E4%B8%80%E4%B8%AA%E7%B1%BB%E4%B8%AD%E7%9A%84%E4%BF%9D%E6%8A%A4%E6%88%90%E5%91%98%E5%92%8C%E7%A7%81%E6%9C%89%E6%88%90%E5%91%98%E3%80%82
  20. 组合

    1. 一个类包含另一个类对象

    2. https://blog.csdn.net/qq_45481606/article/details/119920168
  21. 继承

    1. 作用:减少代码的重复,提高程序段的可读性,后续功能方便添加
    2. 继承方式:public protected private
    3. 基类 & 派生类 | 父类 & 子类
    4. 访问控制和继承
    5. 一个派生类继承了所有的基类方法,但下列情况除外:
      1. 基类的构造函数、拷贝构造函数、析构函数

      2. 基类的重载运算符

      3. 基类的友元函数
    6. 多继承
      1. class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…

        {                   <派生类类体>                };

    7. 多继承(环状继承),A->D, B->D, C->(A,B)
      1. 这个继承会使D创建两个对象,要解决上面问题就要用虚拟继承格式

      2. 格式:class 类名: virtual 继承方式 父类名

      3. 虚继承--(在创建对象的时候会创建一个虚表)在创建父类对象的时候

      4. 虚继承--  避免多继承的命名冲突
    8. 多层继承、菱形继承等

  22. 练习04:

    1. 使用c++实现链表的增删改查

    2. 实现栈、队列

  23. 多继承的构造函数调用顺序【继承皆如此】

    1. 比如说快递箱子,内部的物品是基类,外层箱子是派生类。所以构造顺序为基类、派生类。 当基类(派生类)构造函数有参数时,派生类需要在写构造函数后初始化基类(派生类),默认构造函数无参;当对象消亡时,先拆箱子,之后再取走物品。调用析构的顺序为派生类、基类(派生类)。

    2.  当然基类中的【数据成员、成员方法】,派生类是完全继承的,私有的可继承不可见,基类中的构造函数、拷贝构造函数、析构函数,重载运算符、基类的友元函数是派生类不可继承的。

    3. 在实际生产环境中,尽量避免多继承,尤其是菱形继承、环状继承

  24. 遮蔽(隐藏)

    1. 在继承关系中,派生类中有与基类同名的方法或数据,此时调用该名字默认使用派生类自己的内容,称为遮蔽了基类的内容,常用于将基类的同名函数重新实现。

  25. 覆盖(重写)

    1. 在继承关系中,基类为virtual修饰,派生类与基类中成员方法同名,参数相同
  26. 重载

    1. 形式:函数名一样,参数不同(参数个数不同,参数类型不同,参数顺序不同),这就称为函数重载。

    2. 函数返回值不同不能作为判断重载的条件。

  27. 概念混淆

    1. 重载
      1. 同一个函数的不同表现形式
      2. 条件
        1. 同一个类
        2. 函数名相同
        3. 参数列表不同(个数、类型、顺序)
        4. 返回值不做要求
        5. virtual关键字可有可无
    2. 覆盖(重写)
      1. 继承关系中,派生类对基类同名函数有不同的表现形式
      2. 条件
        1. 有继承关系的类
        2. 函数原型相同(函数名,参数列表)
        3. 返回值没有要求
        4. 基类成员函数必须声明为虚函数(virtual)
    3. 遮蔽(隐藏)
      1. 继承关系中,派生类遮蔽掉基类的成员函数(名字隐藏了基类的方法)
      2. 对基类中成员函数是否有virtual不做要求
      3. 条件
        1. 继承关系
        2. 两种情况
          1. 派生类成员函数与基类成员函数函数原型一致,基类的成员函数没有virtual修饰,派生类中隐藏了基类的函数(区别覆盖)
          2. 派生类成员函数与基类成员函数函数原型不同,基类的成员函数可以有virtual,派生类中也隐藏了基类的函数(区别重载)
  28. 类型兼容原则

    1. 一个公有派生类的对象在使用上可以被当作基类的对象使用,反之禁止
    2. c++允许对象间复制的
      1. 向上转型:(如上述类型兼容原则)编译器会生成对应的函数
      2. 向下转型:编译器生成的默认的函数不一定能够满足
  29. 练习05:

    1. 用person类(name,age,sex)派生出student类(int no,float score),实例化出n个学生,求这些学生的成绩平均值。

    2. 抽象出一个类point(int x,int y),实例化出两个点,求两个点间的距离

  30. 练习中遇到的问题:

    1. 在实现导入其他文件时,先测试下是否能运行
    2. 静态数据成员是独立的空间,对象的空间释放与静态数据成员空间无关
    3. 静态数据成员一定要初始化后使用,静态成员变量只能被静态成员函数调用
    4. 设置成员方法中的默认值时,最好方法声明时设置,并且这个动作只需一次
    5. 常量,引用等初始化列表时,最好方法定义时设置
    6. 继承中,基类构造函数需要参数时,派生类必须要进行初始化传参设置,写在定义时
    7. 构造函数无返回值,可重载,函数名与类名一致,有参
    8. 析构函数无返回值,只有一个,函数名与类名一致,类名前加~,无参
    9. 设置友元类时无需导入友元类的头文件
    10. 在写友元函数时应该先写要定义的类,后写我要声明调用的类,与友元类相反
    11. 友元函数的定义,需要在函数外部定义,内部只做声明
  31. 补充

    1. string是字符串类
      1. string类是一个模板类,位于名字空间std
      2. 可以用 ==、>、<、>=、<=、和!=比较字符串,可以用 + 或者 += 操作符连接两个字符串,并且可以用 [ ] 获取特定的字符。
      3. string特性描述
      4. int size()const;        //返回当前字符串的大小    str.size()
        int length()const;       //返回当前字符串的长度   str.length()​
        ​​​​​​等
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值