C++学习06

.多态: 什么是多态???

一个对象,作用于不同的事物,得到的结果不一样  --  多态

"一个函数可以实现多种不同的功能"

作用: 提高代码的复用性

静态多态:

在程序编译的时候,已经确定要执行的状态  --  函数重载

动态多态:

在程序运行的时候,才能确定执行的状态,  根据用户传入不同的对象, 执行不同的状态

多态实例:

C++
#include <iostream>
using namespace std;
/*
    有一个人, 他有工作 工作内容是什么???
    不知道  -- 不了解是什么工作
*/
// 人 类
class Person
{
public:
virtual void work(){
    cout << "这个人具体工作不详,不知道是干啥的" << endl;
}
};
//职业
//警察
class Police : public Person{
public:
void work(){
    cout << "抓小偷,找孩子" << endl;
}
};

//老师
class Teacher : public Person{
public:
void work(){
    cout << "讲课,留作业" << endl;
}
};

//医生
class Doctor : public Person{
public:
void work(){
    cout << "看病,开药" << endl;
}
};

//定义一个工作接口
void do_work(Person * p){
    p->work();
}

int main(int argc, char const *argv[])
{
    //传入不同参数 -- 作用于不同的类 得到不同的对象 调用不同的work接口
    do_work(new Person);
    do_work(new Police);
    do_work(new Teacher);
    do_work(new Doctor);

    // 一个do_work函数接口, 作用于不同的事物(参数--不同的类)  得到的结果不一样
    return 0;
}

实现动态多态的条件:

  • 基类要有虚函数
  • 继承
  • 派生类重写基类中的虚函数
  • 把派生类的对象 赋值 给基类的指针或者引用, 通过基类调用被重写的接口

二.虚析构

语法:

virtual ~析构函数(){}

举例:

C++
virtual ~new_base(){}
#include <iostream>
using namespace std;

class base
{
public:
     base(){
        cout << "执行base的构造函数" << endl;
    }
virtual ~base(){
        cout << "~执行base的析构函数" << endl;
    }
};
class new_base : public base
{
    char * p;
public:
    new_base(){
        cout << "执行new_base的构造函数" << endl;
        p = new char[1024];
        cout << "分配1024大小的内存空间" << endl;
    }
virtual ~new_base(){
        cout << "~执行new_base的析构函数" << endl;
        delete []p;
        cout << "释放1024大小的内存空间" << endl;
    }
};

//定义一个工作接口
// void test(base * p){
//    delete p;
// }

int main(int argc, char const *argv[])
{
    // 基类指针 指向 派生类堆空间
    // 系统无法调用派生类的析构函数
    // 会导致无法释放派生类中分配的空间(无法释放派生类中的数据成员)
    // 内存泄漏 资源浪费
    base * q = new new_base;
    delete q;
    return 0;
}

总结: 对于析构函数而言, 无论是否用到多态技术, 最好在析构函数前都加上virtual设置为虚析构, 可以万无一失,保证派生类中数据成员会被释放

关于五一作业中的问题:

组合: 一个类中包含了另一个类的对象作为其成员变量,而不是继承了一个类

作用: 提高代码的复用性

私有继承和组合的区别:

1 关系:

私有继承的关系:  两个类是同一个 --两个类之间有关系

私有继承意味着派生类继承了基类的所有成员和方法,但这些成员和方法在派生类外部是不可见的,即它们被隐藏起来,只能通过派生类的接口来访问。

它通常用于表示“是一个”的关系,但这种关系不希望被外部代码所知晓或利用。

组合关系: 一个类里有一个其他类 -- 两个类之间没有任何关系,彼此独立

组合是指一个类包含另一个类的实例作为其成员变量,从而实现功能的复用。拥有者类通过包含其他类的对象来实现某些功能,而不是通过继承获得。当需要将一个类的功能嵌入到另一个类中,并且希望保持这两个类的独立性时,通常会采用组合。这有助于降低类之间的耦合度,并提高代码的可维护性。

C++
#include <iostream>
using namespace std;
extern "C"{
    #include <string.h>
}

/*

根据下面的要求,完成程序编写,要求包含main函数并在main中使用所定义类的对象。

1)定义一个日期类Date,包含年、月、日;

2)定义一个人事管理的Person类,要求包含身份证号pid、出生日期birthday、性别sex、

姓名name、通讯地址address等属性。其中出生出生日期是日期类的对象;

3)要求Date有构造函数(带默认参数)、显示属性函数showDate();Person有构造函数

(带默认参数)、显示属性函数showPerson()。

*/

C++
class Date
{
public:
    Date(int y=2024,int m=5,int d=6):year(y),month(m),day(d){}
    void showDate(){
        cout << year << "年" << month << "月" << day << "日" << endl;
    }
int year;
int month;
int day;
};

class Person
{
public:
    Person(Date d = 0, int pid = 123456, char sex = 'M',const char *name = "ZQ",const char * add = "沈阳"):birthday(d),pid(pid),sex(sex){
        strcpy(this->name,name);
        strcpy(this->add,add);
    }
    void showPerson(){
        cout << this->pid << endl;
        cout << this->name << endl;
        //直接调用另一个类的对象的函数接口
        this->birthday.showDate() ;
        cout << this->sex << endl;
        cout << this->add << endl;
    }

    Date birthday;
    int pid;
    char sex;
    char name[40];
    char add[1024];
};

int main(int argc, char const *argv[])
{
    Date dd(2000,8,8);
    dd.showDate();
    // Person p(dd);
    Person p(dd,2201061,'F',"suquan","漠河");
    p.showPerson();

    return 0;
}

三.纯虚函数 与 抽象类

1.纯虚函数的定义:

virtual 函数返回值类型 函数名(参数) = 0;

举例:

virtual void func() = 0;  //纯虚函数

2.抽象类

定义: 如果一个类中有纯虚函数, 那么他就是抽象类

抽象类的特点: 抽象类不能实例化 (定义对象)

抽象类:  只能想象 不能实际得到这个对象

C++
#include <iostream>
using namespace std;

class Animals{
public:
//  纯虚函数
//定义叫声
virtual void say() = 0;
};   // 拥有一个纯虚函数 此时就是抽象类

//派生类 -- 对抽象类进行实例化
class dog : public Animals
{
public:
    void say(){
        cout << "汪汪汪....." << endl;

    }
};

class cat : public Animals
{
public:
    // void say(){
    //     cout << "喵喵喵...." << endl;
    // }
};

int main(int argc, char const *argv[])
{
    // Animals a;  // 抽象类不能实例化
    dog d;
    d.say();

    cat c;  // 如果在派生类中没有重写纯虚函数,那么派生类也是抽象类 无法实例化
    c.say();
    return 0;
}

注意: 如果在派生类中没有重写纯虚函数,那么派生类也是抽象类 无法实例化

总结抽象类的作用:

在项目初期给代码预留出一些框架功能接口, 让派生类去实现

分析项目功能时, 整理需求, 定义出很多功能接口,但是不是马上就去实现,而是先抽象出来,方便后期去实现,防止后面忘记了

C++
class network

{
    public:

•   //初始化网络功能

virtual void init_network()  = 0;

•   // TCP通信功能
virtual  void tcp() = 0

•   //UDP通信功能
virtual  void udp() = 0

•   // 网络数据的校验功能

•   ........

};

四.C++中的友元

回顾c++类的访问权限:

C++
class base{
public:   // 公有成员: 类内 子类 类外
int a;

protected: // 保护成员: 类内 子类(子类对象不能直接访问protected  但子类的函数中可以直接访问)
int b;

private: //私有成员: 类内
int c;
}

1.友元:

作用: 用来访问类中所有的数据成员

缺点: 破坏了类的封装性, 一般不到万不得已, 不要随便使用友元

2.友元函数

语法:

C++
friend 函数返回值类型 函数名(参数){
    函数体
}

举例:

C++
friend void func(){
    //改函数可以访问声明他的类中的所有成员
}

3.总结友元函数的特点:

  • 当一个类中声明了一个友元函数,  那么这个函数就不再属于该类的成员函数
  • 友元函数必须在类内声明
  • 友元函数可以在类内任意位置声明, 与成员的权限无关

C++
#include <iostream>
using namespace std;

class base
{
public:
int a;

protected:
int b;

private:
int c;

friend void func();

};

// void base::func(){//  加了friend 变成友元后 func不再是base类的成员函数
//base 类的友元函数
void func(){
    base a;
    a.a = 10;
    a.b = 20;
    a.c = 30;
    cout << a.a << "-" << a.b << "-" << a.c << endl;
}

int main(int argc, char const *argv[])
{
   func();
    return 0;
}

4.友元函数不可以继承

C++
#include <iostream>
using namespace std;

class base
{
private:
int a;

//声明一个友元函数
friend void set();
};

class new_base : base
{
private:
int b;

//不能继承  但是可以自己再次声明友元函数
friend void set();
};

void set(){
    base m;
    m.a = 10086;
    cout << m.a << endl;

    new_base n;
    n.b = 10010;  // 友元函数不能被继承
    // 爸爸的朋友 不能继承给儿子
    // 爸爸的朋友没有权限访问儿子的私有

    cout << n.b << endl;

}

int main(int argc, char const *argv[])
{
    set();
    return 0;
}

总结:

1 友元函数不能被继承

2 假如派生类需要友元函数可以访问其私有成员, 可以在派生类中再次声明该函数为友元函数

3 多个类可以对应一个友元函数

4 一个类可以对应多个友元函数

5.友元类

作用: 当一个类做为另外一个类的友元类时, 该类可以访问对方类的一切数据成员

友元类是单向

定义语法:

friend class 类名

举例:

friend class base;  

6.互为友元类

  • 注意: 一定要在要实例化的类  定义之后,再定义函数接口,  否则无法实例化对象
  • 注意: 类外定义类内函数,不要忘了 域操作符

C++
#include <iostream>
using namespace  std;

class base
{
public:
int a;
void show(){
    cout << a << " " << b << " " << c << endl;
}

void set_new_base(); //类内声明 类外定义
protected:
int b;

private:
int c;

// 声明new_base是当前base的友元类
friend class new_base;
};

//在new_base 中对base里的数据成员进行初始化
class new_base
{
public:
    int k;
    void show(){
        cout << k << endl;
        cout << m << endl;
        cout << n << endl;

    }
    void set_base();  //类内声明 类外定义
   
protected:
    int m;
private:
    int n;

friend class base;
};
// 注意: 一定要在要实例化的类  定义之后,再定义函数接口
// 否则 无法实例化对象
// 注意: 类外定义类内函数,不要忘了 域操作符
void base::set_new_base(){
    new_base b;
    b.k = 123;
    b.m = 456;
    b.n = 789;
    b.show();
}
 void new_base::set_base(){
        base a;
        a.a = 100;
        a.b = 200;  //无法直接访问类内 保护和私有成员 可以通过友元类实现
        a.c = 300;
        a.show();   //通过a调用show函数
}    
int main(int argc, char const *argv[])
{
    new_base b;
    b.set_base();

    base c;
    c.set_new_base();

    return 0;
}

目录

一.多态: 什么是多态???

二.虚析构

三.纯虚函数 与 抽象类

四.C++中的友元


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值