突破C++瓶颈,在此一举!
课程介绍
C++ 不仅能兼容 C 语言,并且还继承了 C 语言的运行速度,因此在许多大型项目中都可以看到 C++ 的身影。封装、继承、多态、模板作为 C++ 的重要特性。掌握封装、继承、多态、模板对提高开发效率有着很明显的提升。
本课程容纳了很多知识点和实验操作,学习本课程的关键因素在于动手去做,多做实验并要做相关的记录,这都将是以后开发中的宝贵经验。
本课程共 21 个实验章节,主要针对封装、继承、多态、模板这 4 个特性作为基础进行讲解实验,并且围绕这 4 个特性讲解了很多与之相关的其他知识点。
课程难度
较难
适合人群
- 对 C 语言或者 C++ 有基础知识的同学
- 想要在 C++ 继续深入学习的同学
- 想进入 C++ 实战的同学
只要课程有一点启发,那就是一个重大的提升,本课程也许就是你突破瓶颈的机会,不论你是准备进军 C++ 开发的准程序员还是混迹职场的 C++ 开发程序员,都可以深入学习!
第一章 认识类与对象
知识点
- 认识类与对象
- 内联函数
- string 类
- 类的定义与实例化
官方定义
类:在面向对象编程中是一种面向对象计算机编程语言的构造,是创建对象的蓝图,描述了所创建的对象共同的属性和方法。
对象:通过类创建出对象,又称实例化对象。
深入理解类
类是 C++ 的核心特性,在 C++ 的世界中,可以将所有事物都看作为一个对象,将对象进行封装之后成为一个类,通常被称为用户定义类型。
例如:可以将猫、狗、鸟、桌子、学生、人、三角形、矩形等都封装为一个类,只要在实际编程中用到的都可以抽象封装为一个类。
C++ 相关概念
概念 | 描述 |
---|---|
构造函数 | 类的构造函数是一种特殊的函数,在创建一个新的对象时自动调用 |
析构函数 | 类的析构函数也是一种特殊的函数,在删除所创建的对象时自动调用 |
拷贝构造函数 | 拷贝构造函数,是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象 |
友元函数 | 友元函数可以访问类的 private 和 protected 成员 |
内联函数 | 通过内联函数,编译器试图在调用函数的地方扩展函数体中的代码 |
类成员函数 | 类的成员函数是指那些把定义和原型写在类定义内部的函数,就像类定义中的其他变量一样 |
类访问修饰符 | 类成员可以被定义为 public、private 或 protected。默认情况下是定义为 private |
this 指针 | 每个对象都有一个特殊的指针 this,它指向对象本身 |
静态成员 | 类的数据成员和成员函数都可以被声明为静态的 |
自定义类
假设最近在做一个学校管理系统的项目,首先想到可以将学生定义为一个类,然后发现可以在学生类的基础上再抽象出一个人类的对象,如果需要用到学生的学科,可以进一步将学科也封装为一个,还可以封装文件操作类,数据库操作类等等。
类定义注意事项:
- 定义一个类时,需要使用关键字 class 来进行修饰。
- 一个简单的类可以没有构造函数和析构函数,但是系统自动生成一个默认的构造函数和析构函数。
- 在类中使用关键字 public 、 private 和 protected 来限制数据成员和成员函数,一般使用 public 和 private 来修饰数据成员和成员函数。
- 一般将数据成员封装在 private 关键字下,不让用户直接访问数据成员,而是通过成员函数来进行访问。
- 在类的最后(大括号后)必须要有一个逗号,勿忘。
实例化对象
实例化对象有两种方式,一种是在栈上实例化,另一种是在堆上实例化。
实例化对象注意事项:
- 在栈上实例化的对象,超出定义域对象资源会自动被系统回收。
- 在堆上实例化的对象,最后需要使用 delete 关键字来释放内存,否则会造成内存泄漏。
- 使用栈实例化的对象使用 “.” 来访问数据成员或成员函数,在堆上实例化的对象使用 “->” 来访问数据成员或成员函数。
- 释放完内存后将对象置空,防止野指针。
string 类
C++ 标准库:前人开发时编写的类,并被收录成为通用的标准类,之后的人开发时可以直接使用,避免重复造轮子。string 类是开发时经常会使用到的一个类。
string 类是 C++ 标准库中的字符串类,专用于字符串操作,接下来介绍一下如何使用 string 类。
string 介绍
- string 类头文件
#include<string>
。 - string 类在 std 命名空间内。
- 使用 string 实例化一个字符串类型的对象。
- 对字符串对象执行例如拼接、查找等操作。
string 初始化方式
实例化 | 解释 |
---|---|
string s1; | s1 为空字符串 |
string s2("ABC"); | s2 初始值为 "ABC" |
string s3 = s2; string s3(s2); | s3 初始化为 s2 的一个副本 |
string s4(n, 'c' ); | s4 初始化为字符 'c' 的 n 个副本 |
string 常用操作
以下列出了 string 经常使用的操作,如果还需要用到其他操作可以在 官网 查找 string 类的相关使用方法,里面配有示例程序。
操作 | 解释 |
---|---|
s.empty() | 判断 s 是否为空,如果 s 为空返回 true,否则返回 false |
s.size() | 返回 s 中字符的个数,和 s.length() 功能相同 |
s[n] | 返回 s 中位置 n 的字符,位置从0开始。切记不要越界 |
s1 + s2 | 将 s1 和 s2 连接成新字符串,返回新字符串 |
s1 = s2 | 赋值,将 s2 内容赋值给 s1 |
s1 == s2 | 判断相等,相等返回 true,否则返回 false |
s1 != s2 | 判断不等,不等返回 true,否则返回 false |
s.c_str() | 返回 char*,和 s.data() 功能相同 |
stoi() | 字符串转 int,还有 stol(),stoll() |
stof() | 字符串转 float, 还有 stod(),stold() |
内联函数
官方定义:内联函数又是称作 “在线函数” 或者 “编译时期展开函数” 的一种编程语言结构,用来建议编译器对一些特殊函数进行内联扩展;也就是说建议编译器将制定的函数体插入并取代每一次调用该函数的地方,从而节省每次调用函数带来的额外时间开支。
- 定义内联函数关键字:inline。
- 内联分为普通内联函数和类内联函数。
- 定义内联函数时一般使用于简单的函数,如果函数比较复杂,编译器也将自动取消内联。
编译过程
类内联函数
如下图是使用类内定义一个类的方法(“类的定义域实例化” 小节中会讲到类内定义),而使用类内定义的成员函数编译器会默认将成员函数当做为内联函数进行编译。但如果成员函数比较复杂,编译器也不会将成员函数当做内联函数进行编译。
- 编译器在编译时会将内联函数直接插入到调用内联函数处,这样可以减去调用函数时的开销。
- 在实际开发过程中,可以酌情考虑使用类内定义的方法实现类成员函数。
类的定义与实例化
在学习本小节之前先来学习另外两个知识点:
- 类内定义
- 类外定义
类内定义
类内定义即在类中实现成员函数。
在课程的示例代码中,类中定义的成员函数都是使用的类内定义的方式实现的,在实际的开发中不建议这样做,除非是定义一个非常简单的类或者成员函数。
在内联函数小节中提到过,类内定义的方式编译器会自动尝试将成员函数作为内联函数进行编译,如果成员函数比较复杂,编译器将不会作为内联函数进行编译。
在实际开发过程中需要考虑到程序的架构问题,类内定义适用于一个相对比较简单的程序,考虑到开发时的方便性和时间成本,类外定义是实际程序开发中常用的方法。
类外定义
类外定义有两种方式:
- 同文件类外定义。
- 分文件类外定义。
同文件类外定义就是将类的成员函数定义在类之外的地方,同时类的成员函数使用类作用域来进行定义。在实际项目开发中,类不是很复杂时可以使用该方法,类比较复杂时不推荐使用。
分文件定义类就是将类的定义放在 xxx.h
头文件中,而类的成员函数实现放在 xxx.cpp
文件中。这种做法是做项目时推荐使用的方法,因为这样将类的定义和成员函数分开后,在开发时很容易能够查找到对应的定义和成员函数。
一般情况下文件名和类名相同,便于开发时类管理。
第一章知识点总结
- 深入认识类与对象并讲解 C++ 相关概念。
- 如何使用 string 类。
- 普通内联函数与类内联函数以及编译器对内联函数的处理。
- 学习类内定义与类外定义,开发时常使用分文件类外定义的方法。
- main 函数的返回值为 int 类型,注意不要写成 void 类型。
剩余章节内容,点击《C++ 进阶应用实战》即可学习。