一、函数复写
1、char *mystrcpy(char *dest, const char *src);
char *mystrcpy(char *dest, const char *src)
{
char *tmp = dest;
while (*dest++ = *src++);
return tmp;
}
2、char *mystrcat(char *dest, const char *src);
char *mystrcat(char *dest, const char *src)
{
char *tmp = dest;
while (*dest) {
dest++;
}
while (*dest++ = *src++);
return tmp;
}
3、int mystrcmp(const char *s1, const char *s2);
int mystrcmp(const char *s1, const char *s2)
{
const char *d1 = s1;
const char *d2 = s2;
while (*d1 && *d2 && *d1++ == *d2++);
return *d1 - *d2;
}
4、size_t mystrlen(const char *s);
size_t mystrlen(const char *s)
{
const char *tmp = s;
size_t len = 0;
while (*tmp) {
tmp++;
len++;
}
return len;
}
二、温故知新
1、继承
1)简介
一个新的类获得了已有类的属性和方法,这个形式就是继承
【1】新的类称为子类或者派生类
【2】已有的类称为父类或者基类
书写格式:
class 派生类名 : 访问修饰符 基类名
{
};
2)方式
继承方式 | 基类成员属性 | 派生类成员属性 |
---|---|---|
public | public | public |
protected | protected | |
private | 不可见 | |
protected | public | protected |
protected | protected | |
private | 不可见 | |
private | public | private |
protected | private | |
private | 不可见 |
3)继承-----构造函数与析构函数
派生类不继承基类的构造函数,是通过调用基类的构造方法来给继承的成员进行初始化。
构造函数的调用顺序:先调用基类的构造函数,再调用派生类的 构造函数。
派生类不继承基类的析构函数,与构造函数不同,编译器在继承关系中知道如何调用析构函数。
析构函数的调用顺序和构造函数的调用顺序相反。
4)基类和派生类的函数重名
注意:
【1】派生类的同名函数遮蔽掉了基类的同名函数,在派生类中,这两个函数都存在。
【2】直接调用同名函数,默认访问的是自身类中的函数,如果想要调用基类中的函数需要通过类名指定调用。
5)多继承
C++支持多继承关系,一个派生类可以有多个基类,派生类可以继承多个基类的成员。
如果多继承的两个基类中有重名的函数,在派生类中可以通过基类的类名进行指定。
6)虚继承
虚继承是多继承中特有的概念,如:菱形继承
在零菱形继承中,为了避免在派生类中出现间接基类的成员出现双份,可以使用一个关键字来修饰-----virtual
使用virtual关键字的继承关系就是虚继承,常用于菱形继承中。
2、多态
1)概念
同一个指针,指向基类调用的是基类方法,指向派生类调用的是派生类方法。
2)多态的条件
【1】基类的成员函数一定要用virtual修饰为虚函数,派生类的成员函数可以有virtual修饰,也可以没有。
【2】派生类中的虚函数必须重写基类方法,函数名一样,返回值一样,参数列表一样。
【3】需要具有继承关系
3)重载、重写(覆盖)、遮蔽(隐藏)
4)纯虚函数
【1】函数只有声明,没有实现
【2】函数用virtual关键字修饰
【3】赋值为0,需要在函数声明之后使用=0作为纯虚函数的标志。
【4】包含纯虚函数的类称为抽象类,抽象类不能实例化对象。
【5】抽象类专门用于约定派生类的接口。
----------------------------------------------------------------------
算术运算符 +、-、*、/、%
关系运算符 >、<、>=、<=、==、!=
逻辑运算符 &&、||、!
位运算符 <<、>>、&、|、~、^
赋值运算符 =、+=、-=、*=、/=、%=
下标运算符 []
指针运算符 *、&
分量运算符 .、->
条件运算符 ? :
强制类型转换 (数据类型)
字节运算符 sizeof
自增自减 ++、--
逗号运算符 ,
----------------------------------------------------------------------
三、C++手册(http://cplusplus.com)
1、string类的各种构造函数
#include <iostream>
#include <string>
using namespace std;//打开命名空间
int main(void)
{
string s1;//构造了一个长度为零个字符的字符串(默认构造函数)
string s2("Hello World");//使用的是第4种构造函数
string s3(s2);//使用的是第2种构造函数
string s4(s3, 5);//使用的是第3种构造函数
//输出内容
cout << "s1 = " << s1 << endl;
cout << "s2 = " << s2 << endl;
cout << "s3 = " << s3 << endl;
cout << "s4 = " << s4 << endl;
return 0;
}
2、字符串长度
#include <iostream>
#include <string>
using namespace std;//打开命名空间
int main(void)
{
string s1;//构造了一个长度为零个字符的字符串(默认构造函数)
string s2("Hello World");//使用的是第4种构造函数
string s3(s2);//使用的是第2种构造函数
string s4(s3, 5);//使用的是第3种构造函数
//输出内容
cout << "s1 = " << s1 << endl;
cout << "s2 = " << s2 << endl;
cout << "s3 = " << s3 << endl;
cout << "s4 = " << s1 << endl;
//求长度
cout << "s1.size = " << s1.size() << endl;
cout << "s2.size = " << s2.size() << endl;
cout << "s3.size = " << s3.size() << endl;
cout << "s4.size = " << s4.size() << endl;
cout << "s1.length = " << s1.length() << endl;
cout << "s2.length = " << s2.length() << endl;
cout << "s3.length = " << s3.length() << endl;
cout << "s4.length = " << s4.length() << endl;
return 0;
}
3、取成员
#include <iostream>
#include <string>
using namespace std;//打开命名空间
int main(void)
{
string s1;//构造了一个长度为零个字符的字符串(默认构造函数)
string s2("Hello World");//使用的是第4种构造函数
string s3(s2);//使用的是第2种构造函数
string s4(s3, 5);//使用的是第3种构造函数
//输出内容
cout << "s1 = " << s1 << endl;
cout << "s2 = " << s2 << endl;
cout << "s3 = " << s3 << endl;
cout << "s4 = " << s1 << endl;
//求长度
cout << "s1.size = " << s1.size() << endl;
cout << "s2.size = " << s2.size() << endl;
cout << "s3.size = " << s3.size() << endl;
cout << "s4.size = " << s4.size() << endl;
cout << "s1.length = " << s1.length() << endl;
cout << "s2.length = " << s2.length() << endl;
cout << "s3.length = " << s3.length() << endl;
cout << "s4.length = " << s4.length() << endl;
//取成员
cout << "s2[2] = " << s2[2] << endl;
cout << "s2.at(2) = " << s2.at(2) << endl;
return 0;
}
4、追加字符串
#include <iostream>
#include <string>
using namespace std;//打开命名空间
int main(void)
{
string s1;//构造了一个长度为零个字符的字符串(默认构造函数)
string s2("Hello World");//使用的是第4种构造函数
string s3(s2);//使用的是第2种构造函数
string s4(s3, 5);//使用的是第3种构造函数
//输出内容
cout << "s1 = " << s1 << endl;
cout << "s2 = " << s2 << endl;
cout << "s3 = " << s3 << endl;
cout << "s4 = " << s1 << endl;
//求长度
cout << "s1.size = " << s1.size() << endl;
cout << "s2.size = " << s2.size() << endl;
cout << "s3.size = " << s3.size() << endl;
cout << "s4.size = " << s4.size() << endl;
cout << "s1.length = " << s1.length() << endl;
cout << "s2.length = " << s2.length() << endl;
cout << "s3.length = " << s3.length() << endl;
cout << "s4.length = " << s4.length() << endl;
//取成员
cout << "s2[2] = " << s2[2] << endl;
cout << "s2.at(2) = " << s2.at(2) << endl;
//追加字符串
//s1.append("Are You Ok?");
s1 += "Are You Ok?";
cout << "s1 = " << s1 << endl;
return 0;
}
5、插入字符串
#include <iostream>
#include <string>
using namespace std;//打开命名空间
int main(void)
{
string s1;//构造了一个长度为零个字符的字符串(默认构造函数)
string s2("Hello World");//使用的是第4种构造函数
string s3(s2);//使用的是第2种构造函数
string s4(s3, 5);//使用的是第3种构造函数
//输出内容
cout << "s1 = " << s1 << endl;
cout << "s2 = " << s2 << endl;
cout << "s3 = " << s3 << endl;
cout << "s4 = " << s1 << endl;
//求长度
cout << "s1.size = " << s1.size() << endl;
cout << "s2.size = " << s2.size() << endl;
cout << "s3.size = " << s3.size() << endl;
cout << "s4.size = " << s4.size() << endl;
cout << "s1.length = " << s1.length() << endl;
cout << "s2.length = " << s2.length() << endl;
cout << "s3.length = " << s3.length() << endl;
cout << "s4.length = " << s4.length() << endl;
//取成员
cout << "s2[2] = " << s2[2] << endl;
cout << "s2.at(2) = " << s2.at(2) << endl;
//追加字符串
//s1.append("Are You Ok?");
s1 += "Are You Ok?";
cout << "s1 = " << s1 << endl;
//插入字符串
s2.insert(5, "embsky");
cout << "s2 = " << s2 << endl;
return 0;
}
6、删除字符串
#include <iostream>
#include <string>
using namespace std;//打开命名空间
int main(void)
{
string s1;//构造了一个长度为零个字符的字符串(默认构造函数)
string s2("Hello World");//使用的是第4种构造函数
string s3(s2);//使用的是第2种构造函数
string s4(s3, 5);//使用的是第3种构造函数
//输出内容
cout << "s1 = " << s1 << endl;
cout << "s2 = " << s2 << endl;
cout << "s3 = " << s3 << endl;
cout << "s4 = " << s1 << endl;
//求长度
cout << "s1.size = " << s1.size() << endl;
cout << "s2.size = " << s2.size() << endl;
cout << "s3.size = " << s3.size() << endl;
cout << "s4.size = " << s4.size() << endl;
cout << "s1.length = " << s1.length() << endl;
cout << "s2.length = " << s2.length() << endl;
cout << "s3.length = " << s3.length() << endl;
cout << "s4.length = " << s4.length() << endl;
//取成员
cout << "s2[2] = " << s2[2] << endl;
cout << "s2.at(2) = " << s2.at(2) << endl;
//追加字符串
//s1.append("Are You Ok?");
s1 += "Are You Ok?";
cout << "s1 = " << s1 << endl;
//插入字符串
s2.insert(5, "embsky");
cout << "s2 = " << s2 << endl;
//删除
s2.erase(5, 6);//从第5个字符开始删除,删除6个字符
cout << "s2 = " << s2 << endl;
return 0;
}
7、替换字符串
#include <iostream>
#include <string>
using namespace std;//打开命名空间
int main(void)
{
string s1;//构造了一个长度为零个字符的字符串(默认构造函数)
string s2("Hello World");//使用的是第4种构造函数
string s3(s2);//使用的是第2种构造函数
string s4(s3, 5);//使用的是第3种构造函数
//输出内容
cout << "s1 = " << s1 << endl;
cout << "s2 = " << s2 << endl;
cout << "s3 = " << s3 << endl;
cout << "s4 = " << s1 << endl;
//求长度
cout << "s1.size = " << s1.size() << endl;
cout << "s2.size = " << s2.size() << endl;
cout << "s3.size = " << s3.size() << endl;
cout << "s4.size = " << s4.size() << endl;
cout << "s1.length = " << s1.length() << endl;
cout << "s2.length = " << s2.length() << endl;
cout << "s3.length = " << s3.length() << endl;
cout << "s4.length = " << s4.length() << endl;
//取成员
cout << "s2[2] = " << s2[2] << endl;
cout << "s2.at(2) = " << s2.at(2) << endl;
//追加字符串
//s1.append("Are You Ok?");
s1 += "Are You Ok?";
cout << "s1 = " << s1 << endl;
//插入字符串
s2.insert(5, "embsky");
cout << "s2 = " << s2 << endl;
//删除
s2.erase(5, 6);//从第5个字符开始删除,删除6个字符
cout << "s2 = " << s2 << endl;
//替换字符串
s2.replace(1, 5, "zackweir");//从第1个字节开始替换,替换5个字节
cout << "s2 = " << s2 << endl;
return 0;
}
四、运算符重载
C语言不支持运算符重载,C++支持运算符重载
1、简介
运算符重载,就是对已有的运算符重新进行定义,赋予另一种功能,来适应不同的数据类型。
2、方式
operator重载运算符用于自建类型的运算,可以有两种定义方式
1】作为自建类型的成员函数,定义在类的内部
此时operator的参数数目比具体重载的运算符操作数目少一个,因为此时使用隐含参数this,并将其作为左操作数(第一个操作数)。如果需要将this作为右操作数,只能将operator作为友元函数。
2】作为自建类型的友元函数,定义在类的内部或外部
此时operator的参数数目与具体重载的运算符操作数数目相同。
3、语法
返回值 operator运算符(参数列表);
// 方式一,作为类中的成员函数
Complex operator+(const Complex &c);
//方式二,作为类外部的友元函数
friend Complex operator-(const Complex &c1, const Complex &c2);
4、形式
1】可以作为类的成员函数
2】可以是全局函数,作为类的友元函数
5、不支持重载的运算符
1】sizeof 字节运算符
2】:: 域解析运算符
3】? : 条件运算符
4】.* 、->* 成员指针访问运算符
5】. 成员访问运算符
6】# 预处理运算符
6、可重载的运算符
双目算术运算符 | + (加),-(减),*(乘),/(除),% (取模) |
关系运算符 | ==(等于),!= (不等于),< (小于),> (大于),<=(小于等于),>=(大于等于) |
逻辑运算符 | ||(逻辑或),&&(逻辑与),!(逻辑非) |
单目运算符 | + (正),-(负),*(指针),&(取地址) |
自增自减运算符 | ++(自增),--(自减) |
位运算符 | | (按位或),& (按位与),~(按位取反),^(按位异或),<< (左移),>>(右移) |
赋值运算符 | =, +=, -=, *=, /= , % = , &=, |=, ^=, <<=, >>= |
空间申请与释放 | new, delete, new[ ] , delete[] |
其他运算符 | ()(函数调用),->(成员访问),,(逗号),[](下标) |
7、必须作为类成员的运算符重载
1】= 赋值运算符
2】[] 下标运算符
3】() 函数调用运算符
4】-> 成员访问运算符
8、建议
双目运算符尽量作为全局函数,作为类的友元函数重载
单目运算符尽量作为类的成员函数重载
9、关系运算符的重载
10、输入输出运算符的重载
11、下标运算符的重载
12、自增自减运算符的重载
13、new和delete运算符
14、mystring类的实现
----------------------------------------------------------------------------
atoi
itoa
----------------------------------------------------------------------------
五、任务
1、pid算法 pwm DMA(直接数据处理)
2、OTA \ FOTA升级