)
一. C简介1. 简介作为 C 语言的超集完整保留指针、内存直接操作等底层能力编译生成原生机器码执行效率接近汇编是性能敏感场景的首选。同时支持面向过程、面向对象封装 / 继承 / 多态、泛型编程、函数式编程四种范式适配从底层工具到大型复杂系统的各类开发需求。qmake 是 Qt 自带的构建工具用来自动生成 MakefileqmakeQt 专用构建工具Qt 为自己量身打造语法简单只适合 Qt 项目CMake通用跨平台构建系统C/C 行业标准不止能编译 Qt所有 C 项目都能用。最小代码示例// 引入C标准输入输出头文件cout、endl都在这个头文件里#includeiostream// main函数程序入口程序从main里面开始执行intmain(){// std::cout 控制台输出std::是作用域表示cout属于标准库// 输出运算符把字符串Hello, C打印到控制台// std::endl 换行并且刷新输出缓冲区std::coutHello, Cstd::endl;// 返回0代表程序正常结束返回给操作系统return0;}其中::为作用域解析符。表示函数 / 变量属于哪个命名空间或哪个类。2. 面向过程与面向对象编程面向过程重点是【一步一步怎么做这件事】数据和动作是分开的。数据和函数分开面向对象重点是【谁来做这件事】把东西本身 它能做的动作打包在一起。数据和函数打包到类用public/private做权限控制面向过程编程#includeiostream// 数据单独存放structRect{doublelength;doublewidth;};// 函数动作独立接收外部数据进行处理voidsetRect(Rectr,doublel,doublew){// 简单校验不能是负数if(l0w0){r.lengthl;r.widthw;}else{std::cout长宽不能小于等于0\n;}}doublegetArea(constRectr){returnr.length*r.width;}intmain(){Rect r;setRect(r,5,3);std::cout面积 getArea(r)std::endl;// 缺点外部可以直接乱改数据绕过校验r.length-10;std::cout面积 getArea(r)std::endl;return0;}面向对象编程#includeiostreamclassRect{// private私有成员类外面不能直接访问保护数据private:doublelength;doublewidth;// public对外公开接口外部只能调用这里的函数public:// 设置长宽自带合法性校验voidset(doublel,doublew){if(l0w0){lengthl;widthw;}else{std::cout长宽不能小于等于0\n;}}// 获取面积doublegetArea(){returnlength*width;}};intmain(){Rect r;r.set(5,3);std::cout面积 r.getArea()std::endl;// 下面这一行编译报错length是private外部无法直接修改// r.length -10;r.set(-2,4);// 只能通过set函数修改会触发校验return0;}面向过程有一堆数据写一堆函数去操作它们。面向对象把数据 操作数据的函数打包成一个类锁住内部数据只开放安全接口。二. 什么是类如何创建类C中的类是一种构造类型与C语言的结构体相似。但是有一些扩展不仅可以是变量也可以是函数。通过类定义出来的变量叫做对象。类是创建对象的模板。1. 类的模板// 类的定义class类名{public公有数据protected保护的数据private私有的数据}C 通过public、protected和private来控制成员变量和成员函数的访问权限。也就是能不能使用该类中的成员。public任何人都能访问外部代码、子类、本类protected✅本类内部可以访问✅ **子类继承它的类**可以访问❌外部普通对象不能访问private只有本类内部可以访问子类、外部都不能访问2. 编写一个类栈中实例化对象与堆中实例化对象#includeiostreamusingnamespacestd;classDog{// 不写关键字的时候默认就是privatepublic:string name;intage;voidrun(){cout“run”endl;}}intmain{// 从栈中实例化对象Dog dog1;dog1.namewangcai;// 从堆中实例化对象,要用delete删除,否则会导致内存泄漏Dog*dog2newDog;dog2-age4;deletedog2;;return0;}如果是私有private的是无法访问的会导致报错也可以包括函数三. 构造函数和析构函数1. 定义构造函数创建对象的时候自动调用用来初始化对象。析构函数对象销毁的时候自动调用用来清理资源。2. 构造函数名字必须和类名一模一样没有返回值连 void 都不能写创建对象时编译器自动调用你不用手动调用可以重载多个构造函数参数不一样作用给对象里面的成员变量赋初始值。示例代码classDog{public:Dog();};3. 析构函数名字是~类名前面加波浪号~没有返回值没有参数一个类只能有 1 个析构函数不能重载对象要被销毁时编译器自动调用作用释放内存、关闭文件等收尾清理工作。示例代码classDog{public:~Dog();};两种实例化对象区别1. 从栈中实例化对象自动调用构造离开作用域自动调用析构#includeiostreamusingnamespacestd;classDog{public:Dog(){coutconstructorendl;}~Dog();};Dog::~Dog(){coutdestructorendl;}intmain(){//Dog dog1;return0;}2. 从堆中实例化对象必须手动delete才会调用析构#includeiostreamusingnamespacestd;classDog{public:Dog(){coutconstructorendl;}~Dog();};Dog::~Dog(){coutdestructorendl;}intmain(){//Dog*dog2newDog;deletedog2;return0;}4. 默认构造函数和析构函数在类实例化对象的时候如果没有定义构造函数编译器会合成一个默认的构造函数。当有了对象之后如果没有定义析构函数。则编译器会合成一个默认的析构函数。就像这样啥也没有只要个默认函数#includeiostreamusingnamespacestd;classDog{public:Dog();~Dog();};intmain(){//Dog dog1;return0;}四. 类的继承1.基类和派生类基类父类通用、基础的类。派生类子类在基类的基础上扩展出新功能继承基类的成员属性、函数代码示例#includeiostreamusingnamespacestd;// 基类又叫父类classanimal{public:string name;intage;voidrun(){coutdogs ageageendl;}};// 派生类又叫子类classDog:publicanimal{};intmain(){Dog dog1;dog1.age5;dog1.run();return0;}子类可以调用父类的变量与函数2. 类的继承方式派生类只能访问基类的public成员。保护继承时基类中各成员属性均变为protected。3.私有继承时基类中各成员属性均变为private。五. 函数重载1. 定义同一个作用域里函数名字相同但是【参数列表不一样】就叫函数重载。满足重载函数的条件:函数名完全一样参数列表不一样参数个数不同参数类型不同参数顺序不同多个参数时2. 示例代码#includeiostreamusingnamespacestd;// 版本11个int参数voidshow(inta){cout整数aendl;}// 版本21个double参数参数类型不同 → 重载voidshow(doublea){cout小数aendl;}// 版本3两个int参数个数不同 → 重载voidshow(inta,intb){cout两个整数a,bendl;}intmain(){show(10);// 匹配版本1 intshow(3.14);// 匹配版本2 doubleshow(1,2);// 匹配版本3 两个intreturn0;}