如何禁止一个类被继承?
来源:互联网 发布:sql server新建语句 编辑:程序博客网 时间:2024/05/23 23:10
当我们想将一个类设置为禁止继承时该用什么方式?有两种解决方案。提示:虚继承与友元!!
Way1:强行将该类的构造函数与析构函数均设为 private,并设定该类的一个友元函数来构建该类对象,并返回指针。此时继承自该类的类将无法调用该类的构造函数,因此将在编译时报错
• 缺点:将类的使用变得与普通类不兼容,不能在友元函数外定义类对象,用户定义该类必须知道友元函数 • 优点:简单易理解
Eg:
class A { friend A* get_Aptr(int); A(int i = 0):val(i){} int val; }; A * get_Aptr(int i) { A * ptr = new A(i); //在用完该对象时还需要手动释放内存空间 return ptr; }
分析:在友元函数外将不能获得实例对象本身,只能获得其指针,但实际上,因为 NRVO(Named return value optimical) 的作用,在某些情况下,将可以返回类对象。如:
Eg:
class A { friend A get_A(int); //与之前一样 }; A get_A(int i) { A a(i); return a; } int main() { A a = get_A(3); }
分析:
• 若 A 中未定义复制构造函数,则这种使用 get_A(int)的方式正确,此时编译器进行了 NRV 优化,A a = get_A(3)的这句话中并没有调用复制构造函数,因此,该语句正确(g++ 与 VS2013均正确)
• 若A中定义了复制构造函数,且复制构造函数位于private段,则此时用 get_A(int)的方式在编译时报错,但并不代表并未使用 NRV 优化,只是跟编译器的处理方式有关。个人认为:编译器发现复制构造函数在 private 段就会将复制构造操作认为是错误的操作
• 若A中定义了复制构造函数,且赋值构造函数位于 public 段,则此时使用 get_A(int) 的方式正确,但是否进行了NRV 与编译器有关。对 g++ 此时进行了 NRV 优化,对 VS2013 则未进行 NRV 优化
• 在《深入探索C++对象模型》中,李普曼老师说若未定义复制构造函数将不会开启 NRV 优化;但在现在的编译器中,NRV 优化的开启一般都与复制构造函数没有关系,主要由编译器option来决定。
way2 : 定义一个类A,将其构造函数与析构函数均放在 private 段,并将类 B 设为类A 的友元,让 B 虚继承自 A,B将变为不可继承的类。使用类C 继承类B 来检查是否不可继承
分析:在该过程中有两个重要操作,<1>将 类B 设为类A 的友元,<2>将类B 虚继承自类A。以下逐个分析。
• 将B设为A的友元后,B可以访问A的私有构造函数与析构函数,则B的使用正常,从理论上说,新定义一个类C 将不能继承类B,因为类C 不能访问 A类子对象的构造函数
§ 问题:事实上,若只是如此,将能够通过编译,因为 A类子对象的构造函数将有 B类子对象调用,而 B类子对象是 A类子对象的友元,因此能通过编译§ 解决方法:强行让最底层的派生类访问基类的构造函数,即让 C类对象直接访问 A类子对象的构造函数,而不能让 B类子对象访问 A类子对象的构造函数
• 要使类C 的对象直接访问 A子对象的构造函数,办法是使 A 类成为派生链中的虚基类
§ 虚基类的子对象由继承链中最低层的类对象维护,因此类A 的子对象将由链中最底层的 类C 的对象调用,而类C 没有类A 子对象的构造函数的访问权,因此,类C 的继承操作将报错
说明:
• 缺点:理解起来比较复杂
• 优点:使用不可继承的类与使用一般类相同
0 0
- 如何禁止一个类被继承?
- 如何阻止一个类被继承。
- 如何防止一个类被继承?
- 如何让一个类不能被继承
- 禁止被继承的类【3】
- 如何禁止访问一个网站??
- c++如何防止一个类被其他类继承
- 禁止类继承的方法
- C++中如何让一个类不能被继承
- 如何创建一个不能被继承的类
- c++如何生成一个不能被继承的类
- 如何写一个无法被继承的类
- 如何定义一个不能被继承的类
- c++中如何实现一个不能被继承的类
- 如何定义一个不能被继承的类
- C++中禁止类被继承的方法
- C++中禁止类被继承的方法
- 在C++中禁止类继承
- ActionResult的本质三:JavaScriptResult & JsonResult
- Java基础——原码, 反码, 补码 详解
- 网络中常用的9个命令
- Android 加载图片优化
- 读取文件
- 如何禁止一个类被继承?
- java.net.NoRouteToHostException: No route to host
- C++实现道格拉斯-普克法压缩矢量数据
- ActionResult的本质四:HttpStatusCodeResult & RedirectResult/RedirectToRouteResult
- OC字典练习 -- 中国省市区
- javascript之Ajax获取和设置标头
- sort和qsort函数的用法
- Hibernate教程
- 常用排序算法之JavaScript实现