C++基础--Day6

C++基础--Day6,第1张

C++基础--Day6 继承

● 继承是面向对象的三大特性之一
● 好处:减少重复代码
● 语法:class 子类 : 继承方式 父类
● 子类:派生类
● 父类:基类

继承方式
● 语法:class 子类 : 继承方式 父类
● 继承方式:
○ 公共继承
■ public 和 protected 权限不变
■ 父类中私有成员不能访问
○ 保护继承
■ public 和 protected 都成为 protected 成员
■ 父类中私有成员不能访问
○ 私有继承
■ 父类中的所有成员都变成 private
■ 父类中私有成员不能访问

继承中的对象模型

● 父类中所有非静态成员属性都会被子类继承
● 父类中的私有成员只是被编译器隐藏,不能访问,但是实际被继承了

继承中的构造和析构

● 继承中的构造:先构造父类,再构造子类;
● 继承中的析构:先析构子类,再析构父类;

继承中同名成员的处理方式

● 问题:当子类与父类出现同名的成员,如何通过子类对象,访问到子类或者父类中同名的数据呢?
○ 访问子类同名成员:直接访问即可;
○ 访问父类同名成员:需要加作用域;
■ 如果子类中出现和父类同名的成员函数,子类的同名成员会隐藏掉父类所有同名的成员函数;
■ 如果想访问,必须加作用域;

继承同名静态成员处理方式

● 问题:继承中同名的静态成员在子类对象上如何进行访问?
○ 静态成员和非静态成员出现同名,处理方式一致;
○ 访问子类:直接访问;
○ 访问父类:加作用域;

多继承语法
● C++允许一个类多继承;
○ 语法:class 子类 : 继承方式 父类, 继承方式 父类, ……;
○ 多继承可能会引发父类中有同名成员出现,需要加作用域区分;
○ C++实际开发中不建议使用多继承;

菱形继承
● 菱形继承概念:
○ 两个派生类继承同一个基类;
○ 又是某个类同时继承两个派生类;
○ 这种继承成为菱形继承或者钻石继承;
● 关键字:virtual
○ 在继承的时候加上关键字后变成虚继承;
○ 虚继承中相同的数据是共享的;

多态

多态的基本概念
● 多态是面向对象的三大特征之一
○ 多态的分为两类
■ 静态多态:函数重载和运算符重载属于静态多态,服用函数名;
■ 动态多态:派生类和虚函数实现运行时多态;
○ 静态多态和动态多态的区别
■ 静态多态的函数地址早绑定 - 编译阶段确定函数地址;
■ 动态多态的函数地址晚绑定 - 运行阶段确定函数地址;

动态多态满足的条件

● 有继承关系;
● 子类重写父类的虚函数;
○ 虚函数:函数前用virtual关键字说明;
○ 重写:函数返回值类型相同、函数名相同、函数参数列表完全相同;

多态的优点
● 代码组织结构清晰;
● 可读性强;
● 利于前期和后期的扩展以及维护;
○ 开闭原则:对扩展进行开放,对修改进行关闭;

纯虚函数和抽象类
纯虚函数
● 语法:virtual 返回值类型 函数名 (参数列表) = 0;
● 当类中有了纯虚函数,这个类成为抽象类;
● 抽象类特点:
○ 无法实例化对象;
○ 子类必须重写抽象类中的纯虚函数,否则也属于抽象类;

虚析构和纯虚析构
● 问题:多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码;
○ 父类指针指向父类的对象,则在父类析构的时候,不会调用子类中的析构函数,导致子类如果有堆区属性,出现泄漏。
● 解决方式:将父类中的析构函数改为虚析构或者纯虚析构;
○ 纯虚析构:既要声明也要实现,及需要在内外将其实现,不然不能通过编译;
● 虚析构和纯虚析构的共性
○ 可以解决父类指针释放子类对象;
○ 都需要具体的函数实现;
● 虚析构和纯虚析构的区别
○ 如果是纯虚析构,该类属于抽象类,无法实例化;

● 虚析构语法:virtual ~类名(){}
● 纯虚析构语法:virtual ~类名() = 0;

文件 *** 作

● 程序运行时产生的数据都属于零时数据,程序一旦运行结束都会被释放;
● 通过文件可以将数据持久化;
● C++中对文件 *** 作需要包含头文件;

● 文件类型分为两种:
○ 文本文件:文件以文本的ASCII码形式存储在计算机中,用户一般不能直接读懂它们;
● *** 作文件的三大类:
○ ofstream:写 *** 作
○ ifstream:读 *** 作
○ fstream:读写 *** 作

文本文件

写文件
● 步骤
○ 包含头文件:#include
○ 创建流对象:ofstream ofs;
○ 打开文件:ofs.open("文件路径",打开方式);
○ 写数据:ofs << "写入的数据";
○ 关闭文件:ofs.close();

● 文件打开方式

打开方式解释ios::in为读文件而打开文件ios::out为写文件而打开文件ios::ate初始位置:文件尾ios::app追加方式写文件ios::trunc如果文件存在先删除,再创建ios::binary二进制方式

○ 注意:文件打开方式可以配合,利用 | *** 作符;
○ 例如:用二进制方式写文件ios::binary | ios::out

//
// Created by NJUST'er'wang's on 2022/1/18.
//文本文件 写文件
#include 
#include 
using namespace std;

void test01(){
    
    ofstream ofs;

    ofs.open("test.txt",ios::out);

    ofs << "姓名:王东" < 
读文件 

● 读文件与写文件步骤相似,但是读取方式相对于比较多;
● 步骤
○ 包含头文件:#include
○ 创建流对象:ifstream ifs;
○ 打开文件并判断文件是否打开成功:ifs.open("文件路径",打开方式);
○ 读数据:四种读方式;
○ 关闭文件:ifs.close();

//
// Created by NJUST'er'wang's on 2022/1/18.
//文本文件 读文件
#include 
#include 
#include 
using namespace std;

void test01(){
    
    ifstream ifs;
    ifs.open("test.txt",ios::in);
    if(!ifs.is_open()) {
        cout<<"打开文件失败!"< 

● 读数据

  //first method
    char buf[1024] = {0};
    while (ifs >> buf)
    {
        cout< 
//second method
    char buf2[1024] = {0};
    while(ifs.getline(buf2,sizeof(buf2)))
    {
        cout< 
//third method
    string str;
    while (getline(ifs,str))
    {
        cout< 
//forth method
    char ch;
    while ((ch = ifs.get()) != EOF ) //EOF  end of file
    {
        cout< 
 ifs.close();
}
int main()
{
    test01();
    return 0;
}
 
二进制文件 

● 以二进制的方式对文件进行读写 *** 作;
● 打开方式指定为:ios::binary
写文件
● 二进制文件主要利用流对象调用成员函数write
● 函数原型:ostream& write(const char * buffer,int len);
● 参数解释:字符指针buffer指向内存中一段存储空间。len是读写的字节数;

//
// Created by NJUST'er'wang's on 2022/1/18.
//二进制文件 写文件
#include 
#include 
#include 

using namespace std;

class Person {
    char name[10];
    int age;
public:
    Person(char name[10], int age) {
        strcpy(this->name, name);
        this->age = age;
    }

    char *getName() { return name; }

    int getAge() { return age; }

};

void test01() {
    
    ofstream ofs;

    ofs.open("Person.txt", ios::out | ios::binary);

    Person p = {"唐潇", 24};
    ofs.write((const char *) &p, sizeof(Person));

    ofs.close();
}

int main() {
    test01();
    return 0;
}
读文件

● 二进制方式读文件主要利用流对象调用成员函数read;
● 函数原型:istream& read(char *buffer,int len);
● 参数解释:字符指针buffer指向内存中一段存储空间。len是读写的字节数;

//
// Created by NJUST'er'wang's on 2022/1/18.
//二进制文件的读文件
#include 
#include 
#include 

using namespace std;

class Person {
    char name[10];
    int age;
public:
    Person() {}

    Person(char name[10], int age) {
        strcpy(this->name, name);
        this->age = age;
    }

    char *getName() { return name; }

    int getAge() { return age; }

};

void test01() {
    
    ifstream ifs;

    ifs.open("Person.txt", ios::in | ios::binary);

    if (!ifs.is_open()) {
        cout << "打开文件失败!" << endl;
        return;
    }
    Person p;

    ifs.read((char *) &p, sizeof(Person));

    cout << "name: " << p.getName() << ' ' << "age: " << p.getAge() << endl;

    ifs.close();
}

int main() {
    test01();
    return 0;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5708367.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存