function class(classname, super)
local superType = type(super)
local cls --如果父类既不是函数也不是table则说明父类为空
if superType ~= "function" and superType ~= "table" then
superType = nil
super = nil
end --如果父类的类型是函数或者是C对象
if superType == "function" or (super and super.__ctype == 1) then
-- inherited from native C++ Object
cls = {} --如果父类是表则复制成员并且设置这个类的继承信息
--如果是函数类型则设置构造方法并且设置ctor函数
if superType == "table" then
-- copy fields from super
for k,v in pairs(super) do cls[k] = v end
cls.__create = super.__create
cls.super = super
else
cls.__create = super
cls.ctor = function() end
end --设置类型的名称
cls.__cname = classname
cls.__ctype = 1 --定义该类型的创建实例的函数为基类的构造函数后复制到子类实例
--并且调用子数的ctor方法
function cls.new(...)
local instance = cls.__create(...)
-- copy fields from class to native object
for k,v in pairs(cls) do instance[k] = v end
instance.class = cls
instance:ctor(...)
return instance
end else
--如果是继承自普通的lua表,则设置一下原型,并且构造实例后也会调用ctor方法
-- inherited from Lua Object
if super then
cls = {}
setmetatable(cls, {__index = super})
cls.super = super
else
cls = {ctor = function() end}
end cls.__cname = classname
cls.__ctype = 2 -- lua
cls.__index = cls function cls.new(...)
local instance = setmetatable({}, cls)
instance.class = cls
instance:ctor(...)
return instance
end
end return cls end

  

class函数有两个参数,一个是className, 一个是super。这里的super可以是一个table,也可以是一个函数,但不能是userdata。而这个table又分为两种,一种是映射c++相应的类的派生类,一种是纯lua object。下面就根据这几种情况进行讨论。
	1、当基类是function时。
	如函数为 function test() return cc.CCScene:create() end。在定义派生类SceneA时,将此函数作为参数传入class(name, super)。那么返回的新类实际上就是一个Table,且此table中有两个属性,super = test, __create = test。当我们用这个新类构造对象时,调用SceneA.new();然后new又调用前面的test函数,而test函数返回的是一个userData。所以自定义的派生类实际上是一个Table,而由此派生类实例化出的对象实际上是一个UserData。(注意,lua中Table与UserData不一样)。到这里为止,我们就可以用SceneA.new()来构造对象了,但遗憾的是,这里构造的对象不具有SceneExtend属性(quick封装的几个常用函数)。那么如何解决这个问题呢?只需要改写test函数如下:function test() local scene = cc.CCScene:create()  return SceneExtend.extend(scene) end。这样无疑增加了代码量,但庆幸的是,quick为我们封装了这两步操作,所以我们可以直接用如下函数 function test() return display.newScene() end.
	总结:当我们要继承CCNode,CCScene这种C++类时,用function作为基类。
	2、当基类是table,且type == 1 (这里的type=1表示该基类是c++类的派生类,如①中定义的SceneA)时。
	__create = super.__create, super 中的其他属性,则用for循环全部拷贝到派生类中。
	总结:当我们继承CCNode这种C++类的派生类时(如SceneA),直接用派生类SceneA来作为基类)
	3、当基类是table,且是普通的lua对象时(type = nil),直接用这个对象做基类。

	从上面的new函数可以看到,在实例化对象时,都调用了instance:ctor(...)。所以我们在定义类时,一般要加上该构造函数,若没有,则实际调用的是基类的构造函数。(注意上面的第③中情况,class函数已经为我们添加了ctor函数。)

cocos2dx-lua class解析的更多相关文章

  1. cocos2d-x lua绑定解析

    花了几天时间看了下cocos2d-x lua绑定那块,总算是基本搞明白了,下面分三部分解析lua绑定: 一.lua绑定主要用到的底层函数 lua绑定其本质就是有一个公用的lua_Stack来进行C和L ...

  2. RichLabel基于Cocos2dx+Lua v3.x

    RichLabel 简介 RichLabel基于Cocos2dx+Lua v3.x解析字符串方面使用了labelparser,它可以将一定格式的字符串,转换为lua中的表结构扩展标签极其简单,只需添加 ...

  3. Cocos2d-x Lua 阅读Csv文件,使用数据更方便

    在我的书或出售之前,我的源代码,有Csvshadow文件. 也许这是偏见.我与工作将是最长的轮廓Csv,所以,我会帮助不大喜欢它的游戏. Csv文件,非常格式easy,也就是说,一个数据线,字段之间用 ...

  4. cocos2dx lua 3.10 使用cjson

    本篇介绍如何在lua中使用cjson对数据进行json的encode与decode,首先简单介绍下cjson: Lua CJSON 是 Lua 语言提供高性能的 JSON 解析器和编码器,其性能比纯 ...

  5. cocos2d-x lua 中使用protobuf并对http进行处理

    cocos2d-x lua 中使用protobuf并对http进行处理 本文介绍 cocos2d-x lua 中使用http 和 基于cocos2d-x 对lua http的封装(部分ok) 本博客链 ...

  6. cocos2d-x + Lua接入iOS原生SDK的实现方案[转]

    相信很多朋友在使用cocos2d-x+lua开发游戏时都遇到过接入iOS原生SDK的问题,比如常见的接应用内支付SDK,广告SDK或是一些社交平台SDK等等,我也没少接过这类SDK.这篇文章主要是对我 ...

  7. Cocos2dx lua 3D实例代码

    用cocoside 创建一个项目 cocos2dx lua 项目即可 ,然后替换掉gamescene 就可以,具体效果还有函数的参数,相信大家一看就明白.简单说下ide 创建的 cocos lua 项 ...

  8. cocos2dx lua 绑定之二:手动绑定自定义类中的函数

    cococs2dx 3.13.1 + vs2013 + win10 1.首先按照<cocos2dx lua 绑定之一:自动绑定自定义类>绑定Student类 2.在Student类中增加一 ...

  9. lua标签解析器

    lua 标签解析器 概述 一个类xml标签解析函数,将标签解析成Lua中的表结构它可以用来解析简单xml结构,可以作为RichLabel控件的字符串解析组件(其实它现在就是这么用的;-)) 原理 使用 ...

  10. cocos2d-x lua table数据存储

    cocos2d-x lua table数据存储 version: cocos2d-x 3.6 1. 将table转为json http://blog.csdn.net/songcf_faith/art ...

随机推荐

  1. Java中用HttpsURLConnection访问Https链接

    在web应用交互过程中,有很多场景需要保证通信数据的安全:在前面也有好多篇文章介绍了在Web Service调用过程中用WS-Security来保证接口交互过程的安全性,值得注意的是,该种方式基于的传 ...

  2. Linux系统vi编辑器提示E325: ATTENTION的解决方法

    非正常关闭文件会报这样的警告信息, 原因是系统产生了一个.swp的文件. 删除就行了.(前提是确认.swp文件没用了.) 例如: rm -f /etc/.shadowsocks.json.swp 详情 ...

  3. 关于easyui的问答(来自百度问答)

    求教大神,jquery easyui中$('#table').datagrid('options').queryParams是什么意思 https://zhidao.baidu.com/questio ...

  4. JavaScript RegExp Object 正则表达式入门

    什么是 RegExp? RegExp 是regular expression的缩写. RegExp 对象表示正则表达式,它是对字符串执行模式匹配的强大工具. 当您检索某个文本时,可以使用一种模式来描述 ...

  5. 【DeepLearning】Exercise:Softmax Regression

    Exercise:Softmax Regression 习题的链接:Exercise:Softmax Regression softmaxCost.m function [cost, grad] = ...

  6. 怎么卸载用 make install 编译(源码)安装的软件?

    在linux 中用 ./configure && make && make install 后,如果想删除这个软件我应该怎么删除呢?好像有一个叫"make u ...

  7. 【jquery】$(document).ready() 与window.onload的区别

    Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,不过与window.onload方法还是有区别的. 1)执行时间  wind ...

  8. centos yum源

    #remi的源 rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm rpm --import /etc/pki/r ...

  9. 如何检查后台服务(Android的Service类)是否正在运行?

    private boolean isServiceRunning() { ActivityManager manager = (ActivityManager) getSystemService(AC ...

  10. Android lrucache 实现与使用(Android内存优化)

    什么是LruCache? LruCache实现原理是什么? 这两个问题其实可以作为一个问题来回答,知道了什么是 LruCache,就只然而然的知道 LruCache 的实现原理:Lru的全称是Leas ...