一、C与C++关于数据和函数
00:18
1. 复数和字符串
03:36
1)复数的介绍与内存设计
03:42
内存结构:复数包含实部和虚部两部分,如complex c1(2,1)创建的对象在内存中直接存储两个整数
函数设计:需要为复数类设计加减乘除、共轭复数、正弦函数等运算功能
函数共享:数据可以有多份(不同对象),但处理函数只有一份,通过类的机制实现数据与函数的绑定
2)字符串的特色与内存设计
05:12
指针特性:字符串类内部只包含指针,实际内容存储在指针指向的独立内存空间
内存差异:四个字符串对象在内存中各自只占一个指针的大小(如string* ps = new string)
创建方式:字符串内容需要额外分配内存空间存储(如string s1("Hello"))
3)创建对象的方式
06:41
栈上创建:直接声明方式如complex c2
堆上创建:使用new运算符如complex* pc = new complex(0,1)
初始化方式:可通过构造函数直接初始化(如complex c1(2,1))
4)基于对象与面向对象的区别
06:51
Object Based:针对单个class的设计,如复数类的独立实现
Object Oriented:处理多个classes之间的关系,如继承、组合等设计模式
2. C++程序代码基本形式
07:20
文件组成:包含头文件(.h)和实现文件(.cpp)
包含方式:标准库用尖括号#include <iostream>,自定义文件用双引号#include "complex.h"
扩展名说明:头文件扩展名可能是.hpp或其他,甚至无扩展名
3. C++和C输出
09:31
C风格输出:使用printf需要指定格式符(如%d、%s)
C++风格输出:使用cout <<运算符链式输出,自动识别类型(如cout << "i=" << i << endl)
命名空间:现代C++建议使用#include <iostream>配合using namespace std
4. 头文件写法
12:17
1)头文件防卫式声明的必要性
12:22
重复包含问题:防止同一头文件被多次包含导致重复定义
使用便利性:使用者无需关心include顺序,可直接包含所需头文件
2)头文件防卫式声明的实现
13:21
语法结构:
工作原理:通过预处理器检查宏是否已定义,避免重复包含
3)测试程序对头文件的使用
15:21
包含方式:测试程序通过#include "complex.h"使用自定义头文件
功能验证:测试复数类的各种操作(如加减运算、输出等)
4)编写头文件时的建议
15:56
规范要求:所有头文件都应包含防卫式声明
专业体现:规范的防卫式声明是专业代码的标志
兼容性考虑:适用于个人项目和大型商业开发
5. 头文件布局
基本结构:头文件使用条件编译防止重复包含,格式为#ifndef COMPLEX...#endif
组成部分:
0号位置:前置声明(如class ostream;和class complex;)
1号位置:类声明(class complex{...};)
2号位置:类定义(成员函数实现)
设计顺序:应先完成1和2的编写,再根据依赖关系补充0部分的前置声明
6. 类的声明
1)基本结构
class head:类名声明部分(如class complex)
class body:用大括号包裹的类体内容
数据成员:如double re, im;表示复数的实部和虚部
成员函数:包括构造函数、运算符重载等
访问控制:使用public/private控制访问权限
友元声明:如fr iend complex& doapl(...);
2)模板类实现
模板语法:使用template<typename T>前缀
类型参数化:
数据成员类型:T re, im;
函数返回类型:如T real() const
实例化示例:
complex<double> c1(2.5,1.5);
complex<int> c2(2,6);
3)设计要点
需求分析:根据复数运算需求设计成员函数(如共轭复数运算)
语法特性:
构造函数初始化列表:complex(double r=0, double i=0):re(r),im(i){}
const成员函数:如double real() const { return re; }
运算符重载:complex& operator += (const complex&);
7. 类模板简介
18:50
1)类模板的提出背景
重复代码问题: 当需要实现不同数据类型的相似类时(如double/float/int的复数类),传统方法需要为每种类型单独编写类,导致95%-99%的代码重复
解决方案: C++引入模板概念,允许推迟类型指定,避免重复编码
应用场景: 适用于类中某些成员类型需要灵活变化的情况,如复数类的实部(
rerere
)和虚部(
imimim
)数据类型
2)类模板的写法
19:56
模板声明: 在class前添加template<typename T>,其中T可替换为任意标识符(常用T表示Type)
类型参数化: 将需要灵活指定的类型替换为T,如成员变量T re, im;和成员函数返回值T real()
默认参数: 构造函数仍可设置默认值,如complex(T r=0, T i=0)
3)类模板中typename的使用
20:16
语法意义: typename T告知编译器T是待定的类型参数
命名自由: 类型参数名可任意(如T/A等),但约定俗成使用T表示类型
延迟绑定: 编译器在此时不会检查T的具体类型,直到类被实例化
4)类模板的实例化
21:07
显式实例化: 使用类名<具体类型>语法,如complex<double>
类型绑定: 实例化时T被替换为指定类型,如complex<double>中所有T变为double
多实例支持: 同一模板可生成多个不同版本,如:
5)类模板的概念总结
21:57
模具比喻: 类似物理模具可生成形状相同的产品,类模板生成代码结构相同但类型不同的类
替换机制: 实例化时仅进行类型替换(T→具体类型),其他部分完全保留
代码复用: 实现"一次编写,多类型适用",避免99%的重复编码
应用限制: 模板衍生的语法较复杂,基础使用只需掌握类型参数化概念