c++学习13 2020-02-02

本文深入探讨C++中的五大核心特性:虚析构、纯虚函数、虚继承、联编及单例模式,解析其工作原理与应用场景,帮助读者掌握C++高级编程技巧。

内容

1.虚析构
2.纯虚函数
3.虚继承
4.联编
5.单例模式

一.虚析构

class cFather
{
public:
    ~cFather()
    {
        cout << "cFather" << endl;
    }

};
class cSon : public cFather
{
public:
    ~cSon()
    {
        cout << "cSon" << endl;
    }
};
int main()
{
    cFather* fa = new cSon;
    delete fa;
    system("pause");
    return 0;
}

像这种的只会调用父类的析构函数。但是如果把父类的析构函数变成虚函数,那么子类和父类的都会调用了

class cFather
{
public:
    virtual ~cFather()
    {
        cout << "cFather" << endl;
    }

};

同时,delete还有两句话需要注意:①delete谁就调用谁的析构函数(前提是没有虚函数)
②但是new的空间还是会整体释放的。

二.纯虚函数

1.形式

就是在正常虚函数声明后面写上 = 0

class cFather
{
public:
    virtual void fun() = 0;//纯虚函数
    
};

2.特点

①可以没有函数实现。
②不管有没有函数实现,只要这个类有纯虚函数,那么这个类就不能定义对象。
③子类可以定义/实现这个纯虚函数,一但定义/实现后,子类才能定义对象,父类仍然不能定义对象。

class cFather
{
public:
    virtual void fun() = 0;
    
};
class cSon : public cFather
{
public:
    void fun()
    {
        cout << "sajbdjasjd" << endl;
    }
};

3.抽象类和接口类

抽象类:有纯虚函数的类。
接口类:函数成员全是纯虚函数,包括析构函数。(构造函数除外,因为构造函数不能是虚函数)

三.虚继承(不建议用)

要想明白虚继承,就要知道多继承是什么意思。
多继承说白了就是多个父类。
其中,多继承有一种特殊情况,就是菱形继承,对于这种继承,我们有可能用到虚继承。

无标题.png


比如这种,B和C继承A,然后D继承B和C,对于A内的数据成员a,B和C会各有一份,如果再D.a的话,就会不知道.的是谁的a,就会出现多继承中访问不明确的问题。
解决:使用虚继承。
形式,在public前面加上virtual,也就是在B和C都有的public A的前面加上virtual,那么B和C只是获得了对a的使用权,而不是和之前一样是复制了一个a,同理,D也是有了对a的使用权。那么再D.a就不会报错了。(这个东西类似于静态成员)

不建议用虚继承

四.联编

1.定义

联编就是将模块或者函数合并在一起生成可执行代码的处理过程。(函数调用就是一个例子)
其实联编主要是一种理解性的概念,不是应用。

2.分类

按照联编所进行的阶段不同,联编可分为静态联编和动态联编
其中,静态联编主要是在编译阶段,c语言全是静态联编,c++大部分也是
动态联编主要是在运行阶段,基本只有c++多态那个地方会用
动态联编使用示例

class cFather
{
public:
    virtual void fun()
    {
        cout << "cfather" << endl;
    }
};
class cSon : public cFather
{
public:
    void fun()
    {
        cout << "cson" << endl;
    }
};
int main()
{
    cFather* fa ;
    int b;
    cin >> b;
    switch (b)
    {
    case 1:
        fa = new cSon;
        break;
    case 2:
        fa = new cFather;
        break;
    default:
        fa = new cFather;
    }
    fa->fun();
    system("pause");
    return 0;
}

五.单例模式

说白了就是一个类创建一个对象

步骤/特征

①构造函数设置为private/protected,如果不让继承,就设置为private,使其对外不可见。

class cFather
{
private:
    cFather()
    {

    }
};

②通过静态成员函数申请对象空间,并返回地址。

class cFather
{
private:
    cFather()
    {

    }
public:
    static cFather* createOJ()
    {
        return (new cFather);
    }
 };

③定义一个静态标记,记录对象的个数,并控制。

class cFather
{
private:
    cFather()
    {

    }
public:
    static int nFlag;
    static cFather* createOJ()
    {
        if (1 == nFlag)
        {
            nFlag = 0;
            return (new cFather);
        }
        else
        {
            return NULL;
        }
    }
 };
 int cFather::nFlag = 1;

④析构函数将标记清空,以达到重复申请对象的目的。

class cFather
{
private:
    cFather()
    {

    }
public:
    static int nFlag;
    static cFather* createOJ()
    {
        if (1 == nFlag)
        {
            nFlag = 0;
            return (new cFather);
        }
        else
        {
            return NULL;
        }
    }
    ~cFather()
    {
        nFlag = 1;
    }
 };
 int cFather::nFlag = 1;

int main()
{
    cFather* fa = cFather::createOJ();
    delete fa;
    cFather* fa1 = cFather::createOJ();
    delete fa1;

    system("pause");
    return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值