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中能通过编译,读者想想为什么呢?)

  • 相关阅读:
    积水路面Wet Road Materials 2.3
    门控时钟问题
    饮料机问题
    Codeforces Round #340 (Div. 2) E. XOR and Favorite Number (莫队)
    Educational Codeforces Round 82 (Rated for Div. 2)部分题解
    Educational Codeforces Round 86 (Rated for Div. 2)部分题解
    Grakn Forces 2020部分题解
    2020 年百度之星·程序设计大赛
    POJ Nearest Common Ancestors (RMQ+树上dfs序求LCA)
    算法竞赛进阶指南 聚会 (LCA)
  • 原文地址:https://www.cnblogs.com/wangpei0522/p/4460425.html
Copyright © 2011-2022 走看看