该帖子用督促自己学习,先定一个小目标。每天坚持学习至少不懂的一个知识点,不抄笔记全是个人的理解,坚持一个100天
2022/3/30
虚函数是什么?纯虚函数是什么?抽象函数时什么?多态是什么意思?
虚函数
C++虚函数是定义在基类中的函数,子类必须对其进行覆盖。在类中声明(无函数体的形式叫做声明)虚函数的格式如下
Virtual void display()
我们使用虚函数的目的就是为了,让父类指针可以调用子类重新覆盖的对象(我们只要把父类指针指向子类就可以),从而实现多态(同一表达式体现不同效果):(注意要是我们不使用虚函数的话,利用父类指针就无法调用到子类的函数)
#include<iostream>
using namespace std;
// 基类 Father
class Father {
public:
void display() {
cout<<"Father::display()\n";
}
};
// 子类Son
class Son:public Father {
public:
// 覆盖基类中的display函数
void display() {
cout<<"Son::display()\n";
}
};
int main() {
Father *fp; // 定义基类指针
Son son; // 子类对象
fp=&son; // 使基类指针指向子类对象
fp->display(); // 通过基类指针想调用子类中覆盖的display函数
}
纯虚函数(抽象函数)
抽象方法(纯虚函数就,就是在虚函数的基础上使父类无法创建实例)
某些类,现实项目和实现角度吗,都不需要实例化(不需要创建它的对象)。
用法: virtual + = 0
多态
就是允许同一个的函数名的调用来来实现不同的功能(虽然函数表达式一样,但其实指针指向不同的地方,调用的子类不同了)
下面的worker指针,第一次执行的是Employee,第二次指向Manager,第三次指向Boss
Worker* worker = NULL; //父类的指针null是初始化
worker = new Employee(1, "张三", 1);//
worker->showInfo();
delete worker;
worker = new Manager(2, "李四", 2);
worker->showInfo();
delete worker;
worker = new Boss(3, "王五", 3);
worker->showInfo();
delete worker;
2022/4/6(之前疫情影响封在寝室了,继续更新)
模板
为什么我们要使用模板
为了增强程序代码的可以重复利用性,我们创建出了模板这种代码模式,可以用一个代码实现多种的功能。举例我们要创建一个函数去实现加法,一般我们普通函数只能实现某个特定数据类型的加法,但我们使用模板之后,我们可以实现任意数据类型之间的加法。
什么是模板
模板就是建立通用的模具,提高复用性。就好比我们要做个PPT就先找个模板,再往里面填写内容。
函数模板:函数模板作用:
建立一个通用的函数,其函数返回值类型和形参类型可以不具体制定,用一个**虚拟的类型**来代表。
template< typename T>——声明创建模板
typename——表明其后面的符号是一种数据类型,可以用class代替
T——通用的数据类型,名称可以替换,通常为大写字母
//两个整型交换
void SwapInt(int &a, int &b)//
{
int temp = b;
b = a;
a = temp;
}
//两个浮点型交换
void SwapDouble(double &a,double & b)
{
double temp = a;
a = b;
b = temp;
}
template<typename T>
void MySwap(T& a, T& b)//我们在函数参数类型设置为虚拟数据类型 T
{
T Temp = a;
a = b;
b = Temp;
}
类模板:
建立一个通用类, 类中成员数据可以不具体指定,用一个虚拟的类型来代表
template<class NameType>——声明创建模板
class——表明其后面的符号是一种数据类型,可以用typename代替
T——虚拟的数据类型,名称可以替换,通常为大写字母(下面换成了NameType)
//类模板
template<class NameType,class AgeType>//设定一些虚拟的数据类型
class Person
{
public:
Person(NameType name, AgeType age)
{
this->m_Age = age;
this->m_Name = name;
}
void showPerson()
{
cout << this->m_Name << this->m_Age << endl;
}
NameType m_Name;
AgeType m_Age;
};
void test01()
{
// <>中是模板的参数列表
Person<string, int>p1("张三",10);
p1.showPerson();
}
2022/4/7
值传递,地址传递,引用(指针常量)
void test_zhi(int a,int b)
{
int temp;
temp = a;
a = b;
b = temp;
cout << "值传递函数内部传递" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
}
//创建地址传递函数
void tset_dizhi(int * a, int *b)//因为这个函数要接收的是地址,所以里面应该用*定义,表示定义该变量是地址。
{
//地址传递
int temp;
temp = *a;
*a = *b;
*b = temp;
cout << "地址传递函数内部传递" << endl;
cout << "a = " << *a << endl;
cout << "b = " << *b << endl;
}
void test_yiny(int &a1,int &b1)//因为要接收的是引用,因此要使用&符号定义变量。引用就是起外号,因此呢,这边我们区分一下。我们引用的本质就是一个指针常量,指向是固定的地址
{//引用传递。
//既然是起外号,那其实就跟操作
int temp;
temp = a1;
a1 = b1;
b1 = temp;
cout << "引用传递函数内部传递" << endl;
cout << "a = " << a1 << endl;
cout << "b = " << b1 << endl;
}
int main()
{
int a = 10;
int b = 20;
test_zhi(a, b);
cout << "调用值传递函数结果" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
tset_dizhi(&a, &b);
cout << "调用地址传递函数结果" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
test_yiny(a, b);
cout << "调用引用传递函数结果" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
}
引用的本质
指针常量,他的指向不能改变。只能指向一个指定的变量(但是变量的内容可以改变),指针常量的值是地址
2022/4/8
new在堆区开辟空间问题
-
在堆区创建数据
-
new 返回的是 该数据类型的指针
*p表示p所指向的地址里面存放的是一个int类型的值 。
**p表示p所指向的地址里面存放的是一个指向int类型的指针
开辟空间
int *p=new int;//右边开辟了一个int数据类型存放的空间,返回了一个指针,左边有指针变量p来接受这个返回的指针(也就是该空间的首地址)
//如果是数组,则改成
int *p[]=new int[10];
//这个开辟出来的是数组中有十个元素。
释放空间
delete p;
//如果是数组,那么需要改成
delete[]p;
demo
include<iostream>
using namespace std;
int main( )
{
int * arr = new int [10];#开辟空间
for (int i = 0; i < 10; i++)#往我们开辟的空间里面存放数据
{
arr[ i ] = 100 + i;
}
for (int i = 0; i < 10; i++)#输出我们存放的数据
{
cout << arr[ i ] << endl;
}
delete [ ] arr;#释放空间
return 0;#结束程序
}
2022/4/11
什么是仿函数
就是一个结构体,但我们利用它重构()运算符可以实现调用函数一样的效果
#include<iostream>
using namespace std;
#include<string>
struct ADD
{
public:
int operator()(int x,int y)//重载()运算符
{
return x + y;
}
};
int main()
{
ADD add;
cout << add(1, 2) << endl;//我们在实例上调用了我们重载的函数,这样就好像是调用一个函数一样
}
2022/4/13
return 0; 与return;
return语句有两种形式:
1.return;//不带返回值的return语句,中断循环
2.return 0;//带返回值的return语句,或者返回一个变量或一个函数,程序结束
不带返回值的return语句用于,中断返回值为void类型的函数的执行,而带返回值的return则不行。
总结:return;的作用相当于break;用于中断循环的作用,而return 0;则是return的另一种用法,专用于返回值非void的函数返回其值。
2020/4/15
map/multimap容器
区别:
- map不允许容器中有重复key值元素
- multimap允许容器中有重复key值元素
我们可以通容器的key值,访问到容器的value[key::value]
m1.insert(make_pair(2, 20));
m1[2]=20;
单独访问key或者value it->first(second)
map的大小
在往map里面插入了数据,我们怎么知道当前已经插入了多少数据呢,可以用size函数,用法如下
int nSize = mapStudent.size();
构造函数
有参构造的话,就可以在我们定义结构体的时候就给类的一些变量赋给形参,我们只需要在实例化的时候就传入实参就可以完成赋值
Teacher(int empId, string name,string pwd);
Teacher::Teacher(int empId, string name,string pwd)
{
//初始化属性
this->m_EmpId = empId;
this->m_UserName = name;
this->m_UserPassword = pwd;
}
指针访问的两种表达方式
意思都是通过指针manager去访问结构体中的函数openMenu()
manager->operMenu();
(*manager).operMenu()
指针
abs ——>m_Size = (*abs).m_Size
*abs 就是地址的解引用,找到地址主人
取abs的地址&abs
void cleanPerson(addressbooks* abs) 定义abs为一个地址变量,addressbooks为指针类型
定义指针:
int* float* 都是指针类
7/22 函数重载
利用一个函数名定义多个函数,但是同名函数的形参列表(参数个数、类型、顺序)三个必须要有一个不同
#include<Windows.h>
#include<iostream>
using namespace std;
int Add(int a, int b)
{
return a + b;
}
double Add(double a, double b)
{
return a + b;
}
int main()
{
cout << Add(1,2) << endl;
cout << Add(1.1,2.2) << endl;
system("pause");
return 0;
}