提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
C/C++学习——知识点总结记录(持续更新)
一、动态多态构成的条件
1、必须有继承关系;
2、子类重写父类的虚函数。
二、动态多态与静态多态
1、静态多态
静态多态也被称为编译时多态或早期多态,是指在编译时期就确定了调用哪个方法或函数,编译器根据函数或运算符的参数列表或操作数的类型来选择正确的函数或运算符重载版本。
2、动态多态
动态多态也被称为运行时多态或晚期多态,在运行时期根据对象的实际类型来确定调用哪个方法,主要通过继承和虚函数(Virtual Function)来实现。动态多态使得可以在运行时使用基类指针或引用来调用派生类的方法,实现了多态性。
三、纯虚函数与抽象类
抽象类:当类中有一个纯虚函数时,该类为抽象类
1、抽象类不能实例化对象
2、抽象类中的子类,必须重写父类中的纯虚函数,否则子类仍然是抽象类
示例代码:
class Base
{
public:
virtual void func() = 0; //纯虚函数
};
class Son_1 : public Base
{
};
class Son : public Base
{
public:
void func() override
{
cout << "子类输出" << endl;
}
};
void test_1()
{
// Base b; //报错
// Son_1 s; //报错
Son s; //栈区创建对象
s.func();
Base *s2 = new Son; //堆区创建对象,父类指针指向子类对象
s2->func();
}
四、虚析构与纯虚析构
相同点:虚析构与纯虚析构都可以解决 父类指针释放子类对象问题,同时都需要有具体的代码实现。
不同点:如果是纯虚析构,则该类属于抽象类,无法实例化对象。
示例代码:
#include <iostream>
#include <string>
using namespace std;
// 抽象类
class Animal
{
public:
Animal()
{
cout << "Animal构造函数" <<endl;
}
// 利用虚析构可以解决 父类指针释放子类对象时,释放不干净的问题
// virtual ~Animal()
// {
// cout << "Animal析构函数" <<endl;
// }
//纯虚析构声明后,需要实现
// 同样的,当类中有纯虚构函数时,该类也会变成抽象类,也无法实例化对象
virtual ~Animal() = 0;
virtual void speak() = 0; //纯虚函数
};
Animal::~Animal()
{
cout << "Animal纯虚析构函数" <<endl;
}
class Cat : public Animal
{
public:
Cat(string name)
{
cout << "Cat构造函数" <<endl;
m_Name = new string(name);
}
void speak() override
{
cout << *m_Name << "小猫在说话!" << endl;
}
//析构函数
~Cat()
{
if(this -> m_Name != NULL)
{
delete m_Name;
m_Name = NULL;
cout << "Cat析构函数调用" << endl;
}
}
string *m_Name;
};
void test()
{
Animal *cat = new Cat("Tom");
cat->speak();
// 当父类对象中的析构函数不为虚析构时,不会调用子类中的析构函数
delete cat;
}
int main()
{
test();
return 0;
}
运行结果:
Animal构造函数
Cat构造函数
Tom小猫在说话!
Cat析构函数调用
Animal析构函数
总结:
1、虚析构或者纯虚析构就是用来解决通过父类指针释放子类对象;
2、如果子类中没有堆区数据,可以不写为虚析构或者纯虚析构;
3、拥有纯虚析构的类,也属于抽象类;
五、C++文件读写
1、C++中文件写入方法:
- 包含头文件 fstream:
#include <fstream>
- 创建流对象:
ofstream ofs;
- 指定打开方式:
ofs.open("test.txt",ios::out);
- 写入数据:
ofs << "hello world!\n" <<endl;
- 关闭文件:
ofs.close();
2、C++中文件读取方法:
- 包含头文件 fstream:
#include <fstream>
- 创建流对象:
ifstream ifs;
- 打开文件,并判断是否打开成功:
ifs.open("test.txt", ios::in);
if(!ifs.is_open())
{
cout << "文件打开失败!" << endl;
return;
}
- 读取数据
- 关闭文件:
ofs.close();
读取数据的四种方法:
// 第一种方法
char buf[1024] = {0};
while(ifs >> buf)
{
cout << buf << endl;
}
// 第二种方法
char buf[1024] = {0};
while (ifs.getline(buf, sizeof(buf)))
{
cout << buf << endl;
}
//第三种方法
string buf;
while (getline(ifs, buf))
{
cout << buf << endl;
}
//第四种方法
char c;
while ((c=ifs.get()) != EOF) // EOF为文件尾的标志位
{
cout << c;
}
总结
2023秋招不易,加油!!!