Ever wondered how can you design a class in C++ which can’t be inherited. Java and C# programming languages have this feature built-in. You can use final keyword in java, sealed in C# to make a class non-extendable.

  Below is a mechanism using which we can achieve the same behavior in C++. It makes use of private constructor, virtual inheritance and friend class.

  In the following code, we make the Final class non-inheritable. When a class Derived tries to inherit from it, we get compilation error.

  An extra class MakeFinal (whose default constructor is private) is used for our purpose. Constructor of Final can call private constructor of MakeFinal as Final is a friend of MakeFinal .

  Note that MakeFinal is also a virtual base class. The reason for this is to call the constructor of MakeFinal through the constructor of Derived, not Final (The constructor of a virtual base class is not called by the class that inherits from it, instead the constructor is called by the constructor of the concrete class).

 1 /* A program with compilation error to demonstrate that Final class cannot be inherited */
2 #include <iostream>
3 using namespace std;
4
5 class Final; // The class to be made final
6
7 class MakeFinal // used to make the Final class final
8 {
9 private:
10 MakeFinal()
11 {
12 cout << "MakFinal constructor" << endl;
13 }
14 friend class Final;
15 };
16
17 class Final : virtual MakeFinal
18 {
19 public:
20 Final()
21 {
22 cout << "Final constructor" << endl;
23 }
24 };
25
26 class Derived : public Final // Compiler error
27 {
28 public:
29 Derived()
30 {
31 cout << "Derived constructor" << endl;
32 }
33 };
34
35 int main(int argc, char *argv[])
36 {
37 Derived d;
38 return 0;
39 }

  Output: Compiler Error

  In constructor 'Derived::Derived()': error: 'MakeFinal::MakeFinal()' is private

  In the above example, Derived‘s constructor directly invokes MakeFinal’s constructor, and the constructor of MakeFinal is private, therefore we get the compilation error.

  You can create the object of Final class as it is friend class of MakeFinal and has access to its constructor.

  For example, the following program works fine.

 1 /* A program without any compilation error to demonstrate that instances of the Final class can be created */
2 #include <iostream>
3 using namespace std;
4
5 class Final;
6
7 class MakeFinal
8 {
9 private:
10 MakeFinal()
11 {
12 cout << "MakeFinal constructor" << endl;
13 }
14 friend class Final;
15 };
16
17 class Final : virtual MakeFinal
18 {
19 public:
20 Final()
21 {
22 cout << "Final constructor" << endl;
23 }
24 };
25
26 int main(int argc, char *argv[])
27 {
28 Final f;
29 return 0;
30 }

  Output: Compiles and runs fine

  MakeFinal constructor
  Final constructor

  

  Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

  转载请注明:http://www.cnblogs.com/iloveyouforever/

  2013-11-27  14:20:31

Simulating final class in C++的更多相关文章

  1. java抽象、接口 和final

    抽象 一.抽象类:不知道是具体什么东西的类. abstract class 类名 1.抽象类不能直接new出来. 2.抽象类可以没有抽象方法. public abstract class USB { ...

  2. Java内部类final语义实现

    本文描述在java内部类中,经常会引用外部类的变量信息.但是这些变量信息是如何传递给内部类的,在表面上并没有相应的线索.本文从字节码层描述在内部类中是如何实现这些语义的. 本地临时变量 基本类型 fi ...

  3. Java关键字final、static

    一.final根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类.非抽象类成员方法和变量.你可能出于两种理解而需要阻止改变:设计或效率. final ...

  4. JavaSE 之 final 初探

    我们先看一道面试题: 请问 final 的含义是什么?可以用在哪里?其初始化的方式有哪些? 首先我们回答一下这道题,然后再探究其所以然.  1.final 表示“最终的”.“不可改变的”,意指其修饰类 ...

  5. PHP的final关键字、static关键字、const关键字

    在PHP5中新增加了final关键字,它可以加载类或类中方法前.但不能使用final标识成员属性,虽然final有常量的意思,但在php中定义常量是使用define()函数来完成的. final关键字 ...

  6. final修饰符

    final本身的含义是"最终的,不可变的",它可以修饰非抽象类,非抽象方法和变量.注意:构造方法不能使用final修饰,因为构造方法不能被继承,肯定是最终的. final修饰的类: ...

  7. 浅析Java中的final关键字(转载)

    自http://www.cnblogs.com/dolphin0520/p/3736238.html转载 一.final关键字的基本用法 在Java中,final关键字可以用来修饰类.方法和变量(包括 ...

  8. java关键字extends(继承)、Supe(父类引用空间)、 This(方法调用者对象)、Instanceof(实例类型-判断对象是否属于某个类)、final(最终)、abstract(抽象) 、interface(接口)0

    java 继承使用关键字extends   继承的作用:减少代码量,优化代码 继承的使用注意点: 1子类不能继承父类的私有变量 2.子类不能继承父类的构造方法 3.子类在调用自己的构造方法时 会默认调 ...

  9. files list file for package 'xxx' is missing final newline

    #!/usr/bin/python # 8th November, 2009 # update manager failed, giving me the error: # 'files list f ...

随机推荐

  1. 关于Arrays类的静态方法asList()

    Array.asList():是数组转成集合的方法 List<String> list = Arrays.asList(new String[]{"AA", " ...

  2. Maven下载、安装、配置

    简介 Maven是一个项目管理工具,主要用于Java平台的项目构建.依赖管理和项目生命周期管理. 当然对于我这样的程序猿来说,最大的好处就是对jar包的管理比较方便,只需要告诉Maven需要哪些jar ...

  3. 南大《软件分析》课程笔记——Data Flow Analysis

    南大<软件分析>--Data Flow Analysis @(静态分析) 目录 数据流分析概述 数据流分析应用 Reaching Definitions Analysis(may anal ...

  4. Are we ready for learned cardinality estimation?

    Are we ready for learned Cardinality Estimation 摘要 文章包括三大部分: 对于一个静态的数据库,本文将五种基于学习的基数估计方法与九中传统的基数估计方法 ...

  5. Part 19 AngularJS Services

    What is a service in AngularJSBefore we talk about what a service is in Angular. Let's talk about a ...

  6. JAVA学习(六)

    今天先是把内存知识总结归纳地又学习了一遍,现在可以很清楚地描述JVM的内存是如何操作的了. 静态变量储存在方法区内存中,这个之前没有注意到,温故知新了. 如果一个引用是空的(就是指向null),那它在 ...

  7. PTA7-1 根据后序和中序遍历输出先序遍历

    本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果. 输入格式: 第一行给出正整数N(≤30),是树中结点的个数.随后两行,每行给出N个整数,分别对应后序遍历和中序遍历结果, ...

  8. Python知识整理(一)

    一.Python交互模式(终端上进行) python # 进入到Python交互模式,提示符是 >>> exit() # 退出Python交互模式 python xxx.py # 执 ...

  9. OOP 4.21晚 指针知识点

    1.读法:int* ptr ptr是一个指针指向整型变量 2.指针类型:指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型; 3.指针所指向的类型:只须把指针声明语句中的指针名字和名字左边的指 ...

  10. 这可能是你看过最详细的NodeJS安装配置教程

    博主是一枚Java菜鸡,今天在B站上看一些教程视频的时候偶尔看了一眼评论区,发现好多人在Node和Vue安装的位置卡住了,便决定今晚肝出一套最详细的NodeJS安装配置的教程 本文适合初次接触Node ...