• C++快速入门


    基本知识

    面向对象的编程:
    1、自己创建类
    2、自己创建对象

    • 类的形式:
    class student 
    {
    	srting name;
    	int age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 公有、私有
    • 私有的函数需要借用公有的方法调用
    class student 
    {
    public://外部可读写
    	srting name;
    	private://外部看不到 外部不可读写
    	int age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 使用一个类:

    student Jane;//创建一个 student 类的对象 名字将Jane Jane.name = “xiaohua”;//赋值

    • 什么是成员函数
    不同的函数可以使用一样的名字,但是形成不同
    class student 
    {
    public:
     	srting name;
     	int age;
    	 bool set (int a);
    	 bool set (srting a);//两函数形参不同
    }
    //成员函数的定义:
    bool set (srting a)
    {
    	name = a;
    	return true;
    }
    bool set (int a)
    {
    	age = a;
    	return true;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    构造函数

    不带参数的构造函数

    class student 
    {
    public:
    	srting name;
    	int age;
    	student();//这就是构造函数,没有形参,没有返回值,并且名字和类的名字一致
    }
    student::student()//构造函数定义,冒号两边一样,没有输入值
    {
    	age = 20;//构造函数里面,可以对全部的成员变量一个默认值
    	name = "xiaohua";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    以后我再主函数定义新的变量时,变量就会有一个默认值,就是构造函数里面定义的

    带参数的构造函数

    class student 
    {
    public:
    	srting name;
    	int age;
    	student();//这就是构造函数,没有形参,没有返回值,并且名字和类的名字一致
    	student(int a, string b);//带参数的构造函数,还是保存和类一样的名字,根据不同的参数进行区别
    	
    }
    student::student()//构造函数定义,冒号两边一样,没有输入值
    {
    	age = 20;//构造函数里面,可以对全部的成员变量一个默认值
    	name = "xiaohua";
    }
    
    student::student(int a, string b)//构造函数定义,冒号两边一样
    {
    	age = a;//构造函数里面,将输入的值赋值给对象
    	name = b;
    }
    
    int main()
    {
    	student aa;//没有带参数的构造函数默认赋值
    	student bb(23,"小白");//在定义对象时赋值
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    析构函数

    student *p = new student(88,"愚公");//创建一个指针p,指向一个新的对象
    delete p;//删除指针
    
    //析构函数,执行删除指针时会调用
    student :: ~student ()
    {
    	cout<<"delete object";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    常成员函数const

    • 一个方法只读取属性,而不修改属性,就是常成员函数
    class student 
    {
    public:
    	srting name;
    	int age;
    	bool set (int i);//普通成员函数声明,又叫方法
    	bool read() const;//后面加const,表示这个函数只读不写
    	
    }
    bool student :: read() const//后面加const,表示这个函数只读不写
    {
    	cout<<name;//打印姓名
    	cout<<age;//打印年龄
    	return true;
    }
    
    int main()
    {
    	student aa;//创建对象
    	aa.read();//在创建对象后,调用read方法
    	return 0;
    }
    
    //实现上可以不使用const,普通方法也可以读数据,加const只是为了安全起见,防止意外修改数据。
    //更加不正规的做法就是直接读取:aa.age,在正规的程序当中还是会使用const来读取。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    静态成员函数

    • 静态成员数据 ( static):描述全局,又与具体的对象属性无关的变量
    • 读取静态成员数据的方法,叫静态成员函数
    class student 
    {
    public:
    	srting name;
    	int age;
    	student();//这就是构造函数,没有形参,没有返回值,并且名字和类的名字一致
    	static int cnt://static 表示静态成员数据,统计有多少个对象
    	static int count()://static 表示静态成员函数,返回有多少个对象
    	
    }
    
    student::student()//构造函数定义,冒号两边一样,没有输入值
    {
    	age = 20;//构造函数里面,可以对全部的成员变量一个默认值
    	name = "xiaohua";
    	cnt = cnt + 1;
    }
    
    int student ::count()
    {
    	return cnt;//返回静态成员数据,统计有多少个对象
    }
    
    int main()
    {
    	student aa;//创建对象
    	student bb;//创建对象
    	aa.count();//bb.count();//student ::count();不依赖对象的静态函数
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    正规写法

    class student 
    {
    public:
    	bool set (int i);//普通成员函数声明,又叫方法
    	bool read() const;//后面加const,表示这个函数只读不写
    private:
    	srting name;
    	int age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 一般把方法全部放到public中
    • “属性”放在privatezho
    • 目的是防止类的外部随意篡改数据
    • 通过函数来修改数据时,一般都具有防错机制,满足条件才能修改

    派生继承

    
    
    class student 
    {
    public:
    	bool set (int i);//普通成员函数声明,又叫方法
    	bool read() const;//后面加const,表示这个函数只读不写
    private:
    	srting name;
    	int age;
    }
    
    class undergraduate : public student //本科生类定义,冒号后面表示从student 类公有派生而来
    {
    	public:
    		srting course;//这个行新增定义一个公开的字符串属性 course,比如本科生的课程大学物理
    }
    
    class postgraduste : public student //研究生类定义,冒号后面表示从student 类公有派生而来
    {
    	public:
    		srting research;//这个行新增定义一个公开的字符串属性 research,比如研究生的研究方向:芯片设计
    }
    
    int main()
    {
    	undergraduate aa;//创建本科生对象
    	postgraduste bb;//创建研究生对象
    	aa.set(33);//子类可以调用父类的方法
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 将student 当中的private变为protect,研究生类就可以继承student 的protect下的内容,而且对应student 来说,protect下的内容和private下的是一样的
    > class undergraduate : private student//私有继承,继承所得的public下的内容变为private 下的,不继承private 下的内容
    > class undergraduate : protect student//保护继承,继承所得的public下的内容和protect 下的内容都为protect 下的内容
    
    • 1
    • 2
    • 子类只能调用父类的构造函数

    子类的构造函数

    class undergraduate : public student //本科生类定义,冒号后面表示从student 类公有派生而来
    {
    	public:
    		srting course;//这个行新增定义一个公开的字符串属性 course,比如本科生的课程大学物理
    		undergraduate();//
    		undergraduate(int a,string b,string c);//
    }
    
    undergraduate :: undergraduate()
    {	
    	course = "math"
    	
    }
    //带参数的构造函数
    undergraduate :: undergraduate(int a,string b,string c):st`在这里插入代码片`udent (a,b)
    {	
    	course = c;
    }
    int main()
    {
    	undergraduate aa;//创建本科生对象
    	postgraduste bb(22,"xiaohua","math");//创建对象,并且赋初值
    	aa.set(33);//子类可以调用父类的方法
    	return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    多态

    • 重载:同名的方法,根据不同形参,执行不同的方法
    • 隐藏:父类当中定义一个方法,子类可以重新定义,重新定义的方法输入格式相同或者不同都可以
    class student 
    {
    public:
    	bool set (int i);//普通成员函数声明,又叫方法
    	bool read() const;//后面加const,表示这个函数只读不写
    	void study(bool a);
    private:
    	srting name;
    	int age;
    }
    void student :: study(bool a)
    {
    	cout<<"好好睡觉"
    }
    
    class undergraduate : public student //本科生类定义,冒号后面表示从student 类公有派生而来
    {
    	public:
    		srting course;//这个行新增定义一个公开的字符串属性 course,比如本科生的课程大学物理
    		void study(bool a);
    }
    
    void undergraduate :: study(int a)
    {
    	cout<<"好好吃饭"
    }
    
    int main()
    {
    	student aa;//创建父对象
    	postgraduste bb;//创建子对象
    	bb。study(2);//打印好好吃饭
    	aa.study(ture);//打印好好睡觉
    	bb。study(ture);//报错,父类方法被隐藏了
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 指针

      • 父类的指针可以指向子类,子类的指针不可以指向父类
      • 指向子类的父类指针也只能调用父类的方法和属性,不能调用子类的方法和属性
    • 虚函数(virtual)

    class student 
    {
    public:
    	bool set (int i);//普通成员函数声明,又叫方法
    	bool read() const;//后面加const,表示这个函数只读不写
    virtual	void study();
    private:
    	srting name;
    	int age;
    }
    void student :: study()
    {
    	cout<<"好好学习"
    }
    
    class undergraduate : public student //本科生类定义,冒号后面表示从student 类公有派生而来
    {
    	public:
    		srting course;//这个行新增定义一个公开的字符串属性 course,比如本科生的课程大学物理
    	virtual	void study();
    }
    
    void undergraduate :: study()
    {
    	cout<<"好好吃饭"
    }
    class postgraduste : public student //研究生类定义,冒号后面表示从student 类公有派生而来
    {
    	public:
    		srting research;//这个行新增定义一个公开的字符串属性 research,比如研究生的研究方向:芯片设计
    	virtual	void study();
    }
    void postgraduste :: study()
    {
    	cout<<"开开心心"
    }
    
    int main()
    {
    	student aa;//创建父对象
    	postgraduste bb;//创建子对象
    	undergraduate cc;//创建子对象
    	student *p;
    	p = &aa,
    	p->study();//打印好好学习
    	p = &bb,
    	p->study();//打印开开心心
    	p = &cc,
    	p->study();//打印好好吃饭
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    纯虚函数与抽象函数

    class student 
    {
    public:
    	student ();//抽象类也有构造函数
    	student (int a,string b);//构造函数重载
    virtual	void study() =0;//声明方法,前面有virtual还有=0,表示纯虚函数,只有声明没有定义
    }
    
    int main()
    {
    	student aa;// 报错 不允许创建对象
    	postgraduste bb;//创建子对象
    	undergraduate cc;//创建子对象
    	student *p;
    	p = &bb,
    	p->study();//打印开开心心
    	p = &cc,
    	p->study();//打印好好吃饭
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    回调实例展示

    
    #include 
    #include 
    #include 
    #include "stdio.h"
    using namespace std;
    
    class student {
     public:
      string name;
      int age;
      ~student();
      student();  // 这就是构造函数,没有形参,没有返回值,并且名字和类的名字一致
      student(
          int a,
          string
              b);  // 带参数的构造函数,还是保存和类一样的名字,根据不同的参数进行区别
    
      bool set(int a);
      bool set(string a);  // 两函数形参不同
    
      bool read() const;  // 后面加const,表示这个函数只读不写
      static void stuone(int i) {
        std::cout << "I an first student" << std::endl;  // 打印姓名
        std::cout << i << std::endl;                     // 打印姓名
      }
      void FunB1(void (*callback)()) {
        printf("I'am ProgramB.FunB1() and be called..\n");
        callback();
      }
    };
    
    // 成员函数的定义:
    bool student::set(string a) {
      name = a;
      return true;
    }
    bool student::set(int a) {
      age = a;
      return true;
    }
    
    student::student()  // 构造函数定义,冒号两边一样,没有输入值
    {
      age = 20;  // 构造函数里面,可以对全部的成员变量一个默认值
      name = "xiaohua";
    }
    
    student::student(int a, string b)  // 构造函数定义,冒号两边一样
    {
      age = a;  // 构造函数里面,将输入的值赋值给对象
      name = b;
    }
    // 析构函数,执行删除指针时会调用
    student ::~student() { std::cout << "delete object" << std::endl; }
    
    bool student ::read() const  // 后面加const,表示这个函数只读不写
    {
      std::cout << name << std::endl;  // 打印姓名
      std::cout << age << std::endl;   // 打印年龄
      return true;
    }
    typedef void (*FuncPtr1)(int);
    std::map<std::string, FuncPtr1> g_TmpCmdMap;
    std::map<std::string, int> g_Tmpage;
    
    // 回调函数的注册函数
    int registfun(int age, string name, void (*FuncPtr1)(int)) {
      student aa;  // 创建对象
      aa.set(age);
      aa.set(name);
      aa.read();  // 在创建对象后,调用read方法
      g_Tmpage[name] = age;
      g_TmpCmdMap[name] = FuncPtr1;
      // aa.FunB1(FuncPtr1);
      return 0;
    }
    
    int checkoutfun(string name) {
      std::map<std::string, FuncPtr1>::iterator g_TmpCmdMap1;
      std::map<std::string, int>::iterator g_Tmpage1;
      g_TmpCmdMap1 = g_TmpCmdMap.find(name);
    
      if (g_TmpCmdMap1 == g_TmpCmdMap.end()) {
        printf("%s %d 11111111111111111111\n", __func__, __LINE__);
        return 0;
      }
    
      g_Tmpage1 = g_Tmpage.find(name);
      if (g_Tmpage1 == g_Tmpage.end()) {
        printf("%s %d 222222222222222222\n", __func__, __LINE__);
        return 0;
      }
      printf("%s %d 33333333333333333\n", __func__, __LINE__);
      g_TmpCmdMap[name](g_Tmpage[name]);
      return 0;
    }
    int main(int argc, char *argv[]) {
      printf("%s %d \n", __func__, __LINE__);
      registfun(181, "hhh1", student ::stuone);
      registfun(182, "hhh2", student ::stuone);
      registfun(183, "hhh3", student ::stuone);
      registfun(184, "hhh4", student ::stuone);
      registfun(185, "hhh5", student ::stuone);
      registfun(186, "hhh6", student ::stuone);
      registfun(187, "hhh7", student ::stuone);
      printf("%s %d ============================ \n", __func__, __LINE__);
      checkoutfun("hhh2");
      checkoutfun("hhh99");
      return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
  • 相关阅读:
    matlab自定义添加设置工具箱
    5个基于.Net Core值得推荐的CMS开源项目
    Linux安装MySQL
    有向图的强连通分量
    简单理解 Sentinel 滑动窗口实现原理
    [附源码]java毕业设计幼儿园管理系统
    【Java实战项目】【超详细过程】—大饼的图片服务器2
    一种基于局部适应度景观的进化规划的混合策略
    很普通的四非生,保研破局经验贴
    2022-10-27-梯度下降法结合线性回归预测公交车数量和GDP关系
  • 原文地址:https://blog.csdn.net/qq_43441284/article/details/127989592