zoukankan      html  css  js  c++  java
  • 写一个不能被继承的类,且能正常使用

    写一个不能被继承的类,且能正常使用

    实验室同学今天面试,上来被问的第一个题就是”写一个不能被继承的类“

    这个问题分享出来的时候,我惊呆了,因为脑子没一点思路(这是什么鬼东西,项目里从来没有用过,课堂上也没听过,在博客、问答区也没遇见过)。C++里没有相关的语法定义,也没有特定的设计。冷静判断,觉得这应该就是设计模式一类的东西(这方面确实很欠缺)。不扯了,经过查阅资料,这题是Adobe 07年的面试题,是我太年轻~ 原题是:”写一个不能被继承的类,且能正常使用“,难度更大,考查了两个知识点。

    首先,不能被继承的类,也就是它的子类继承它后不能正常的实例化。其实,如果能考虑到这里,就很简单了:子类需要实例化父类,将父类的构造函数设为private,子类就无法实例化了。再进一步,子类的析构函数需要调用父类的析构函数,所以将父类的析构函数设为private也能解决我们的问题。

    问题的后半句将难度提升了两个数量级:且能正常使用。如果将父类的构造函数设为private,它自己就无法正常,它自己的对象没法正常的声明、实例化。将构造函数设为了private非常的像单例模式,促使我们想通过friend函数解决无法实例化的问题(当然,如果析构函数是private就是无法释放,它们同样的原理,下文不再复述)。

    哦,不不,停住,仔细看题目需求,这里要求正常的使用该类,而不是依靠额外的函数途径去申请一个实例。

    这确实是一个难题~如果没有看过答案,我肯定想不出来。我记得计算机世界有一句名言”一切难题都可以通过增加一个中间层去解决“

    要正常的使用该类,它的构造函数和析构函数必然是public访问权限。我们为它增加一个虚继承的父类,它是父类的friend(友元),父类的构造函数是private。

    直接上代码:

    class A;
    
    class final
    {
        friend class A;//class关键字不可省略,否则在g++中不能编译通过
        final()
        {}
    };
    
    class A : virtual public final
    {
    public:
        A()
    {}
    }; class B : public A { public: B() { } };

    class A 是final的friend,所以A可以调用final的构造函数。

    因为A虚继承了final,往后所有继承A的子类,都必须自己实例化final,以保证final在对象中的唯一性

    所以,B继承A后,需要自己调用虚继承的父类final的构造函数。显然,B不是final的友元,不能访问private中的构造函数。

    (注意,将上面的final的构造函数换成了析构函数~final()后,在VS2013中能通过编译,读者想想为什么呢?)

    ============== End

  • 相关阅读:
    SpringCloud学习笔记(2):使用Ribbon负载均衡
    SpringCloud学习笔记(1):Eureka注册中心
    Spring发送电子邮件
    CentOS7.5安装部署GitLab流程
    Shell流程控制及循环
    Shell的条件测试表达式
    Shell变量的数值运算
    Shell脚本简单入门
    Flutter Weekly Issue 58
    Android 开发技术周报 Issue#282
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/11170403.html
Copyright © 2011-2022 走看看