你将收获

学完后,您对c++语言本身的掌握已经很完整、全面了,您可以尝试寻找月薪在1万到1.5万的工作了!

适用人群

(1)有c语言基础,比如知道c中函数、指针、结构等概念。 (2)希望打牢基础并想在c++开发道路上长足发展。

课程介绍

本教程适合那些只有一点点c语言编程知识的新手,也适合那些c++98标准已经掌握的不错但对c++11/14/17新标准基本无所知的c++开发老手,欢迎大家尽早加入学习,请大家从授课目录,讲解课程时长、演示范例详尽程度,试听后收获四个方面评估本教程的质量。

课程目录

学员评价

4.8
  • 95%
  • 0%
  • 0%
  • 0%
  • 5%
  • cxmiii 2020-05-24 20:41

    好好备课再来讲吧,把constexpr的含义搞搞清楚。 另外,把外语学学好,别老是把'C'读成"希", 读到英文单词还都说的是拼写。

  • 灬为了丶梦想 2020-04-14 17:11

    期待老师更深入的Java和数据结构课程

  • derrickrose2020 2020-03-30 10:41

    这是第二次买老师的课了, 感觉还不错,比自己埋头看书,没有老师教的感觉好多了(小白自学者),看了王老师的课,以前书上晦涩的内容豁然开朗。前期感觉有点跟不上,心里还有点慌,不过后面老师会提醒我在哪一章讲过,于是我会回去重新学习。这样我就一步步跟上了老师的步伐。感谢王老师。

没有更多了

同学笔记

  • derrickrose2020 2020-04-06 18:53:03

    来源:基类与派生类关系的详细再探讨 查看详情

     
          //一:派生类对象模型的简述

    //Men mymen; // 子类(派生类)对象 包含多个组成部分(也就是多个子对象)
    ////(1) 一个是 含有派生类自己定义的成员变量 或者成员函数的子对象
    //// (2) 一个是该派生类所继承的基类的子对象  ,这个子对象中包含的是基类中定义的成员变量
    //Human* phuman = new Men; //基类指针 可以new派生类对象 因为派生类对象基础部分
    //                            //换句话说 我们可以用基类指针new一个派生类对象
    //                            //编译器帮助我们做了一个隐式转换
    //
    ////二:派生类构造函数
    //Men mymen; //既调用基类构造函数 又调用派生类构造函数
    //派生类实际是使用 基类的构造函数 ;

    //B b(10, 12, 13);  //先执行基类的构造函数 在执行派生类的构造函数
                      //先执行派生类的构造函数 再执行基类的构造函数

     

    //三:既当父类又当子类
    //class gra{...};
    //class fa:public gra{..};//gra是fa的直接基类
    //class son:public fa{...};//gra是son的间接基类(爷爷类)
    //继承关系一直传递  构成了一种继承链

    //四:不想当基类的类


    //C++11标准  :final 加载类名后边

    //五: 静态类型与动态类型
    //Human* phuman = new Men();
    //Human& q = *phuman;

    //静态类型就是变量声明的类型  静态类型就是编译的时候是已知的
    //动态类型:指的是这个指针/引用 所代表的 内存中的对象的类型。 这里是Men类型。
            //动态类型 是运行时候才能知道
    //动态类型: 静态类型这种概念 只有基类


    //六: 派生类向基类的隐式类型转换

    //Human* phuman = new Men;
    //Human& q = *phuman;
    //这种转换能够成功 是以为每个派生类对象都包含一个基类的 对象部分 所以基类的引用或者指针是可以
    //基类对象 能独立存在 也能作为派生类对象的一部分存在

    //并不存在派生类到基类的类型转换


    //Men* phu = new Human;

    //Men men;
    //Human* phuman = &men;
    ////Men* pmen = phuman; //不可以  编译器发现基类不能转成派生类
    ////如果基类中有虚函数的话  可以通过dynamic_cast可以转换
    //
    //Men* pmen = dynamic_cast<Men*>(phuman);
    //if (pmen != nullptr)
    //{
    //    //{...}
    //}

    //父类与子类之间的拷贝与赋值
    //Men men;
    //Human human(men); //用派生类对象来定义并初始化基类对象 这个会导致基类的拷贝函数的执行

    //赋值运算符
    //Men men;
    //Human human;
    //human = men;

     

    //结论
    //用派生类对象为一个基类对象初始化或者赋值时 只有该派生类对象的

     

     

  • derrickrose2020 2020-04-05 19:39:06

    来源:RTTI、dynamic_cast、typeid、虚函数表 查看详情


        //一:RTTI是什么 (run time  type Identification):运行类型识别

        //Human* phuman = new Men;
        //Human& q = *phuman;  //*phuman 表示指针phuman所指向的对象
        //// RTTI 我们可以把这个称呼看成是一种系统提供给我们的一种能力 或者功能。
        ////(1)dynamic_case运算符: 能够将基类的指针或者 引用安全的转换为派生类的指针或者引用
        ////(2) typeid 运算符: 返回指针或者引用所指对象的实际类型
        ////补充: 基类中必须有一个虚函数 不然两个运算符结果不一样
        //phuman->eat();

        //二:  dynamtic_case运算符  如果该运算符能够转换成功 说明这个指针实际上是要转换到的那个类型

        //Human* phuman = new Men;
        //Men* p = (Men*)(phuman);
        //p->testfunc();

        //Human* phuman = new Men;
        //Men* pmen = dynamic_cast<Men*>(phuman);
        //if (pmen != nullptr)
        //{
        //    cout << "phuman是一个Men类型" << endl;
        //    pmen->testfunc();
        //}    
        //else
        //{
        //    cout << "phuman不是一个Men类型" << endl;
        //
        //}

        //对于引用,如果用dynamic_case转换失败

        //Human* phuman = new Men;
        //Human& q = *phuman;
        //try
        //{
        //    Men& menbm = dynamic_cast<Men&>(q);
        //    cout << "phuman实际上是一个Men类型" << endl;
        //    menbm.testfunc();  
        //
        //}
        //catch(std::bad_cast)
        //{
        //    cout << "phuman 实际上不是一个Men类型" << endl;
        //
        //}


        //typeid 运算符

        //Human* phuman = new Men;
        //Human& q = *phuman;
        //cout << typeid(*phuman).name() << endl;  //class Men
        //cout << typeid(q).name() << endl;       //class Men

        //char a[10] = { 5,1 };
        //int b = 10;
        //cout << typeid(a).name() << endl;
        //cout << typeid(b).name() << endl;
        //cout << typeid(19.6).name()<< endl;
        //cout << typeid("asd").name()<< endl;

    //typeid 主要是为了比较两个指针是否指向同一类型的对象
    //(1);两个指针定义的类型相同(Human)
    //Human* phuman = new Men;
    //Human* phuman2 = new Women;
    //if(typeid(phuman) == typeid(phuman2))
    //{
    //    cout << "phuman和phuman2是同一种类型【看指针定义】" << endl;
    //
    //}

     

    //(2)  
    //Human* phuman = new Men;
    //Men* phuman2 = new Men;
    //Human *phuman3 = phuman2;
    //if (typeid(*phuman) == typeid(*phuman2))
    //{
    //    cout << "phuman和phuman2指向的对象类型相同" << endl;
    //
    //}
    //if (typeid(*phuman2) == typeid(*phuman3))
    //{
    //    cout << "phuman2和phuman3指向的对象类型相同" << endl;
    //
    //}

    //Human* phuman = new Men;
    //if (typeid(*phuman) == typeid(Men))
    //{
    //    cout << "phuman指向Men" << endl;
    //    
    //}
    //if (typeid(*phuman) == typeid(Human))
    //{
    //    cout << "phuman指向Human" << endl;
    //
    //}

    //基类必须有虚函数 否则上边的条件不成立

     

    //四:type_info类
    //
    //Human* phuman = new Men;
    //const type_info& tp = typeid(*phuman);
    //cout << tp.name() << endl;
    //
    ////b) == ,!=
    //Human* phuman2 = new Men;
    //const type_info& tp2 = typeid(*phuman2);
    //if (tp == tp2)
    //{
    //    cout << "tp和tp2类型相同" << endl;
    //}
    //Human* phuman3 = new Men;
    //const type_info& tp3 = typeid(phuman3);
    //if (tp == tp3)
    //{
    //    cout << "tp 和 tp3 类型相同" << endl;
    //}

    //五: RTTI与虚函数表

        //C++中如果类含有虚函数  编译器就会对该类产生一个虚函数表
        //虚函数表里有很多项 每一项都是一个指针 每个指针指向的是这个类里的各个虚函数的入口地址
        //虚函数表项里 第一个表项很特殊 , 它指向的不是虚函数的入口地址 它指向的实际上是咱们这个类所关联 的typeid

        

     

  • derrickrose2020 2020-04-04 19:14:46

    来源:友元函数、友元类、友元成员函数 查看详情

    #include <iostream>
    #include "Human.h"
    #include "men.h"
    #include "Women.h"
    #include"func.h"
    #include "A.h"
    #include "C.h"

    using namespace std;

    //void func(const Men &tmpmen)
    //{
    //    tmpmen.funcmen();
    //}
    //class C;  //类C声明
    //class A
    //{
    //
    //private:
    //    int data;
    //    friend class C;
    //};
    //class C
    //{
    //public:
    //    void callCAF(int x, A &a)
    //    {
    //        a.data = x;
    //        cout << a.data << endl;
    //    }
    //    void callCAF2(A& a)
    //    {
    //        a.data;
    //    }
    //
    //};
    //

     

    int main()
    {
    //    std::cout << "Hello World!\n";
    //
    //    二:  派生类对象定义时调用构造函数的顺序
    //      当定义子类对象时  是要调用父类和子类的构造函数的 而且 父类的构造函数的函数体先执行
    //
    //
    //    三 public 、protected ,private
    //    总结 : 三种访问权限
    //    men.m_Age = 12;
    //    men.m_prol = 14;
    //   
    //
    //    四:函数 遮蔽
    //    Men men;
    //    men.funcpub();
    //    men.funcpub;
    //    也就是子类中 如果有了一个同名函数 那么父类中  不管有几个同名函数 子类中都无法访问。
    //    如果我们确实是想调用父类中的同名函数  怎么办?
    //    (1)  在子类的成员函数中调用 父类名::函数名
    //    men.samenamefunc(12);
    //
    //    (2) using :
    //
    //    c++11: 让父类同名函数在子类中可见。
    //    通过using这个关键字 让父类的同名函数 在子类可见
    //
    //    men.samenamefunc();
    //    men.samenamefunc(12);
    //
    //    说明这种using 、、、 只能指定函数名  则凡是基类中的public 在子类中都可见
    //    引入的主要目的 是用来实现在子类对象中调用父类的重载版本.  该函数在父类的参数和子类中不一样
    //
    //

            //一:基类指针  派生类
       /* Human* phuman = new Human();
        Men* pmen = new Men;*/

        //新玩法; 父类指针可以new'一个子类对象;  父类指针很强大
        //Human* phuman = new Men;  //这个是可以的;
        //Men* pmen = new Human;
         //phuman->funcHumen();


         //二 :虚函数

        //phuman->eat();  //调用的父类的eat函数 。 因为phuman是父类指针

         // 那如何调用Men和Women中的eat函数。
        //Men* pmen = new Men;
        //pmen->eat();

        //Women* pwomen = new Women;
        //pwomen->eat();

        //Human* phuman2 = new Human;
        //phuman2->eat();
        //一旦某个函数(在基类)
      //  Human* phuman = new Men;
      ////  phuman->eat();  //调用的是父类的
      //  phuman->eat();
      //  phuman->Human::eat();
      //  delete phuman;


      //  phuman = new Women;
      //  phuman->eat();
      //  delete phuman;

      //  phuman = new Human;
      //  phuman->eat();
      //  delete phuman;

        //为了避免你在子类中写错虚函数 ,在C++11里  你可以在函数声明中加上 override关键字
                // 这个关键字用在 “子类”中 而且是虚函数专用
        //override就是用来说明派生类的虚函数  你用这个关键字之后  编译器就会默认你覆盖了 父类的参数


        //final final 也是虚函数专用  用在“父类中” 如果我们在父类的函数声明中 家里final的话  那么任何尝试 覆盖该函数的操作的话 都会出错

        //动态绑定: 运行的时候才决定你的phuman 对象绑定到哪个eat()函数上运行;
                
        //三:多态性


        //四:纯虚函数

        //一旦类里 有纯虚函数了 那么你就不能生成类的对象了
       // Human human;
        //Human *phuman = new Human ; 不合法
        //抽象类的主要目的 是用来统一调用子类对象
        //所以大家记住两点
        //函数纯虚函数的类 叫抽象类 不能用来生成;类对象  主要用于当成基类来生成子类用的
        //
        //Human* phuman = new Men;
        //phuman->eat2();
        
        // Human* phuman = new Women;


    //五: 基类的析构函数 一般写成虚函数
    //Men men;
    //Men* pmen = new Men;
    //delete pmen;

    //Human* phuman = new Men;
    //delete phuman;//没有执行子类的析构函数 坏事

     


    //friend
    //一 : 友元函数
    //public protected,private;
    //只要让函数func称为类Men的友元函数  ,那么func这个函数
    //Men men;
    //func(men); //显示了text

    //总结了一下 : 友元函数func(。。。) :是个函数  通过声明为某个类men的友元函数


    //二:友元类   类可以把其他的类定义成友元类  如果你是我的友元类  那么你就可以访问我的所有成员

    //A a;
    //C c;
    //c.callCAF(3, a);  //3

    //注意每个类都负责自己的友元函数和友元类
    // 友元关系不能被继承
    //友元关系是单向的  比如上边的类C是类A的友元类
    //友元关系是没有传递性的  比如类B是类A的友元类  类C


    //三: 友元成员函数
       
    A a;
    C c;
    c.callCAF(3,a);

     

     

    //c.h

    // day14.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //
    #ifndef __C__
    #define __C__

    class A;
    class C
    {

    public:
        void callCAF(int x, A &a);
        void callCAF2(int x, A& a);

    };

     

     


    #endif //~


    ////a.h

    // day14.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //
    #ifndef __A__
    #define __A__

    #include<iostream>

    #include"C.h"
    class A
    {
        friend void C::callCAF(int x, A& a);
        friend void C::callCAF2(int x, A& a);

    private:
        int data;

     

    };


    #endif

     

没有更多了