类(class)能不能自己继承自己(转)
类(class)能不能自己继承自己
不行,继承关系会出现环。
假设类A继承类A。
那么要新建一个类A的对象,就必须先建立一个类A父类的对象。这是一个递归的过程,而且没有终止条件。会死循环的。
从编译的角度讲,声明类A的时候需要用到它的父类,但是此时类A还没有声明。所以是不可行的。
=== 犹豫了一下的分割线 ===
评论区有同学说了模版这种妖术可以解决。我仔细想了想,貌似还真有编程语言可以实现。
比如在Lua中一种常见的继承方式是使用metaclass。此时只要将metaclass指向自己就好了。此时的继承关系依旧是个环…区别在此处的环形继承关系是在运行时的时候创建的,所以可以硬上,之前的是要求运行前就搞定的,所以在创建的时候会有问题…此时的继承关系不影响你使用:P。同理其他的像JS啊之类的东东也可以有类似的用法。然而并没有什么卵用……
严格意义上的继承不可能实现,否则将会出现循环依赖.若分离内存布局的"继承",则可以通过CRTP继承包含自身类型信息的基类;如@白如冰 的答案里提到的;(这应该说是更像将自身的类型信息"传递"给了基类,也算是一种非严格意义另类的自身继承_(:3」∠)_ ).
这种"继承"自身还是有需求的,基于性能的考虑;主要是通过CRTP可实现静态多态:
在编译期确定函数的调用省去了虚表
Demo:
#include <iostream> template<class _Ty>
class Base
{
public:
void func() //call the function implemented in derived class
{
static_cast<_Ty*>(this)->func();
}
}; class Derived_A
:public Base<Derived_A>
{
public:
void func() //implement
{
std::cout << "Derived Class A" << std::endl;
}
}; class Derived_B
:public Base<Derived_B>
{
public:
void func() //implement
{
std::cout << "Derived Class B" << std::endl;
}
}; template<class _Ty>
void invoke(Base<_Ty>& obj)
{
obj.func();
} int main()
{
Derived_A A;
Derived_B B;
invoke(A);
//Output: Derived Class A
invoke(B);
//Output: Derived Class B
return ;
}
因为继承关系是非对称(反对称且非自反)的。
http://www.zhihu.com/question/31848825
类(class)能不能自己继承自己(转)的更多相关文章
- ECMAScript6 中 类的封装与继承
ECMASCRIPT6中实现了class关键字,这样使我们更容易也更形象的进行类的操作 <script type="text/javascript"> class OF ...
- iOS 杂笔-24(常用类到NSObject的继承列表)
iOS 杂笔-24(常用类到NSObject的继承列表) NSString NSObject->NSString NSArray NSObject->NSArray ↑OC基本类都直接继承 ...
- java类为什么是单继承。类的继承,实现接口。
java中提供类与类之间提供单继承. 提供多继承会可能出现错误,如:一个类继承了两个父类,而两个父类里面都有show()方法. class Fulei1{ public void show(){ Sy ...
- java中关于类的封装与继承,this、super关键字的使用
原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/5454849.html. this关键字: this代表当前对象,它有以下几种用途: 1.本类 ...
- 实现Square类,让其继承自Rectangle类,并在Square类增添新属性和方法,在2的基础上,在Square类中重写Rectangle类中的初始化和打印方法
实现Square类,让其继承自Rectangle类,并在Square类增添新属性和方法,在2的基础上,在Square类中重写Rectangle类中的初始化和打印方法 #import <Found ...
- 类和对象:继承 - 零基础入门学习Python038
类和对象:继承 让编程改变世界 Change the world by program 上节课的课后作业不知道大家完成的怎样?我们试图模拟一个场景,里边有一只乌龟和十条鱼,乌龟通过吃鱼来补充体力,当乌 ...
- Javascript学习6 - 类、对象、继承
原文:Javascript学习6 - 类.对象.继承 Javasciprt并不像C++一样支持真正的类,也不是用class关键字来定义类.Javascript定义类也是使用function关键字来完成 ...
- Kotlin——从无到有系列之中级篇(四):面向对象的特征与类(class)继承详解
如果您对Kotlin很有兴趣,或者很想学好这门语言,可以关注我的掘金,或者进入我的QQ群大家一起学习.进步. 欢迎各位大佬进群共同研究.探索 QQ群号:497071402 进入正题 在前面的章节中,详 ...
- Java类是如何默认继承Object的
前言 学过Java的人都知道,Object是所有类的父类.但是你有没有这样的疑问,我并没有写extends Object,它是怎么默认继承Object的呢? 那么今天我们就来看看像Java这种依赖于虚 ...
随机推荐
- document.getElementById()使用方法
document.getElementById使用 语法:oElement = document .getElementById ( sID ) 參数:sID――必选项. 字符串 (String) . ...
- Ubuntu 12.04开启3D桌面特效
1.设定软件源,更新软件 点击左边栏Dash主页(Ubuntu图标),输入更新管理器,会出现更新管理器,打开后点设置,弹出软件源对话框,为确保能够正常更新,选主服务器 点击检查,更新完后,点重启 2. ...
- Perl中的单行凝视和多行凝视
同其它大多数编程语言一样.Perl中的单行凝视也是#开头.比如: #print "Hello,World!"; 但多行凝视.不同的语言有不同的凝视方式,比方说: Java,C/C+ ...
- MVC 使用EF Code First数据迁移之添加字段
PM> add-migration 20161109 -Force 正在为迁移“20161109”搭建基架.此迁移文件的设计器代码包含当前 Code First 模型的快照.在下一次搭建迁移 ...
- 返璞归真 asp.net mvc (2) - 路由(System.Web.Routing)
原文:返璞归真 asp.net mvc (2) - 路由(System.Web.Routing) [索引页] [源码下载] 返璞归真 asp.net mvc (2) - 路由(System.Web.R ...
- 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern)
原文:乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) 作者:webabc ...
- 更新代码和工具,组织起来,提供所有博文(C++,2014.09)
为了更容易地管理各种规范和工具所涉及的资源鲍文,现在把这些资源迁移 GitHub 在,趣者可前往下载. C++ 1.<通用高性能 Windows Socket 组件 HP-Socket v3.2 ...
- Nexon由Xsolla全球支付服务
韩国游戏公司纳克森决Nexon定从今年10月1日起,与Xsolla开展Playspan的合作,向全球提供更好的服务. 当Nexon的玩家随时想购买NX点数的时候.Xsolla的服务能够进入程序,让您的 ...
- Android设计模式(十)--生成器模式
回头看自己写的东西,大概Android当自己控制的定义,编写代码适用性比较高.但是,看看没有什么技术含量,因此,当在学习设计模式,想想有些东西是否可以改善,例如: 自己定义Dialog是Android ...
- SoC嵌入式软件架构设计II:没有MMU的CPU虚拟内存管理的设计和实现方法
大多数的程序代码是必要的时,它可以被加载到内存中运行.手术后,可直接丢弃或覆盖其它代码. 我们PC然在同一时间大量的应用,地址空间差点儿能够整个线性地址空间(除了部分留给操作系统或者预留它用).能够觉 ...