• 32.C++不能被继承的类[C++ Final Class]


    【题目】

    用C++设计一个不能被继承的类。 

    【分析】

    这是Adobe公司2007年校园招聘的最新笔试题。这道题除了考察应聘者的C++基本功底外,还能考察反应能力,是一道很好的题目。

    在Java中定义了关键字final,被final修饰的类不能被继承。但在C++中没有final这个关键字,要实现这个要求还是需要花费一些精力。

    首先想到的是在C++ 中,子类的构造函数会自动调用父类的构造函数。同样,子类的析构函数也会自动调用父类的析构函数。要想一个类不能被继承,我们只要把它的构造函数和析构函数都定义为私有函数。那么当一个类试图从它那继承的时候,必然会由于试图调用构造函数、析构函数而导致编译错误。

    可是这个类的构造函数和析构函数都是私有函数了,我们怎样才能得到该类的实例呢?这难不倒我们,我们可以通过定义静态来创建和释放类的实例。基于这个思路,我们可以写出如下的代码:

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     

    ///////////////////////////////////////////////////////////////////////
    // Define a class which can't be derived from
    ///////////////////////////////////////////////////////////////////////
    class FinalClass1
    {
    public:
        
    static FinalClass1 *GetInstance()
        {
            
    return new FinalClass1;
        }

        
    static void DeleteInstance( FinalClass1 *pInstance)
        {
            
    delete pInstance;
            pInstance = 
    0;
        }

    private:
        FinalClass1() {}
        ~FinalClass1() {}
    };

    这个类是不能被继承,但在总觉得它和一般的类有些不一样,使用起来也有点不方便。比如,我们只能得到位于堆上的实例,而得不到位于栈上实例。能不能实现一个和一般类除了不能被继承之外其他用法都一样的类呢?办法总是有的,不过需要一些技巧。请看如下代码:

    【代码】

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     

    template <typename T>
    class Base
    {
        
    friend T;
    private:
        Base() {}
        ~Base() {}
    };

    class FinalClass:  virtual public Base<FinalClass>
    {
    public:
        FinalClass() {}
        ~FinalClass() {}
    };

    class NewClass: public FinalClass
    {
        
    // can pass at compiler time,but can not pass at runtime.
    };

    int _tmain(int argc, _TCHAR *argv[])
    {
        FinalClass fc;
        FinalClass *fcnew = 
    new FinalClass();
        
    delete fcnew;

        
    //NewClass nc; // ERROR!

        
    return 0;
    }

    现在看看我们的Finalclass类,继承于Base,Base为虚基类。因为它是Base的友元,所以它可以访问基类的私有构造函数,以及析构函数。编译运行时是正确的。也就是说,可以创建堆上的对象,并且可以构建栈上的对象

    可否继承?假如它作为一个基类被一个类继承,在编译时是完全可以通过的。这一点没有什么疑问,问题就出在运行时:当子类在构造对象时,因为是虚继承,所以子类的构造函数会直接去调用Base类的构造函数,而Base的构造函数是私有的,运行错误error!!!

    这就是一个真正不能被继承的类。

    【参考】

    http://zhedahht.blog.163.com/blog/static/25411174200793181548842/

    http://www.cnblogs.com/Braveliu/archive/2013/01/03/2842739.html

    http://blog.csdn.net/lazy_tiger/article/details/2224899

    个人学习笔记,欢迎拍砖!---by hellogiser

    Author: hellogiser
    Warning: 本文版权归作者和博客园共有,欢迎转载,但请保留此段声明,且在文章页面明显位置给出原文连接。Thanks!
    Me: 如果觉得本文对你有帮助的话,那么【推荐】给大家吧,希望今后能够为大家带来更好的技术文章!敬请【关注】
  • 相关阅读:
    torch.nn.functional中softmax的作用及其参数说明
    from __future__ import包的作用
    python textwrap的使用
    深度学习框架PyTorch一书的学习-第五章-常用工具模块
    python实现命令行解析的argparse的使用
    pytorch visdom可视化工具学习—2—详细使用-1—基本使用函数
    pytorch visdom可视化工具学习—2—详细使用-3-Generic Plots和Others
    pytorch visdom可视化工具学习—2—详细使用-2-plotting绘图
    硬盘没有显示
    Eclipse中syso 快捷键 Alt + / 不能使用的问题
  • 原文地址:https://www.cnblogs.com/hellogiser/p/3738892.html
Copyright © 2020-2023  润新知