• cocos2dx-lua class解析


    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函数。)
  • 相关阅读:
    Java Web学习总结(9)——servlet和Jsp生命周期解读
    Java Web学习总结(9)——servlet和Jsp生命周期解读
    Java Web学习总结(10)——Session详解
    Java Web学习总结(10)——Session详解
    Mysql学习总结(6)——MySql之ALTER命令用法详细解读
    Mysql学习总结(6)——MySql之ALTER命令用法详细解读
    十大热门问题集锦,一眼看懂华为云数据库黑科技
    python上下文管理器细读
    关于token你需要知道的
    使用app测试Modelarts在线服务
  • 原文地址:https://www.cnblogs.com/zhepama/p/4287020.html
Copyright © 2020-2023  润新知