【元表】

元表中的键为事件(event),称值为元方法(metamethod)。

通过函数getmetatable查询不论什么值的元表,通过函数setmetatable替换表的元表。

setmetatable(仅仅能用于table)和getmetatable(用于不论什么对象)

语法:setmetatable (table, metatable),对指定table设置metatable      【假设元表(metatable)中存在__metatable键值。setmetatable会失败】

语法:tmeta = getmetatable (tab)。返回对象的元表(metatable)             【假设元表(metatable)中存在__metatable键值,当返回__metatable的值】

【元方法】

元表能够控制对象的数学运算、顺序比較、连接、取长、和索引操作的行为。

当Lua对某值运行当中一个操作时。检查该值是否含有元表以及对应的事件。

假设有,与该键关联的值(元方法)控制Lua怎样完毕操作。

每一个操作的键是由其名字前缀两个下划线“__”的字符串。比如。操作“加(add)”的键是字符串"__add"。

特别一提,要获取给定对象的元方法。我们使用表达式

metatable(obj)[event]

它应被解读为

rawget(getmetatable(obj) or {}, event)

就是说,訪问一个元方法不会调用其它元方法,并且訪问没有元表的对象不会失败(仅仅是结果为nil)。

"add": + 操作。 

以下的getbinhandler函数定义Lua怎样选择二元操作的处理程序。首先尝试第一操作数,假设它的类型未定义该操作的处理程序。则尝试第二操作数。

function getbinhandler (op1, op2, event)

 return metatable(op1)[event] or metatable(op2)[event]     

end

事件:

add

sub

mul

div

mod

pow

unm 一元操作-

concat 连接操作..

len 取长操作#

eq 同样操作==

lt 小于操作<

le

index 索引訪问table[key],參数table,key

newindex 索引赋值table[key] = value, 參数table, key, value

call lua调用

__index元方法:

依照之前的说法,假设A的元表是B,那么假设訪问了一个A中不存在的成员。就会訪问查找B中有没有这个成员。这个过程大体是这样,但却不全然是这样。实际上,即使将A的元表设置为B。并且B中也确实有这个成员,返回结果仍然会是nil。原因就是B的__index元方法没有赋值。依照我的理解,__index方法是用来确定一个表在被作为元表时的查找方法。

【用户数据和元方法】

Userdata:

A userdata offers a row memory area, with no predefined operations in Lua, which we can use to store anything (分配指定数量的内存在栈上。把数据已用户自己定义的数据结构存放进去)



lua_newuserdata() -- allocates a block of memory with the given size, pushes the corresponding userdatum on the stack, and returns the block address



Metatable:

The usual method to distinguish one type of userdata from other userdata is to create a unique metatable for that type.

Lua code cannot change the metatable of a userdatum, it cannot fake our code (Lua 不能改变userdata里面的metatable,所以userdata的metatable能够用作唯一标示符来识别userdata,这里metatable拿来推断是否传入了正确的userdata參数)

【继承】

cocos2dx里的继承:

function class(classname, ...)
local cls = {__cname = classname} local supers = {...}
for _, super in ipairs(supers) do
local superType = type(super)
assert(superType == "nil" or superType == "table" or superType == "function",
string.format("class() - create class \"%s\" with invalid super class type \"%s\"",
classname, superType)) if superType == "function" then
assert(cls.__create == nil,
string.format("class() - create class \"%s\" with more than one creating function",
classname));
-- if super is function, set it to __create
cls.__create = super
elseif superType == "table" then
if super[".isclass"] then
-- super is native class
assert(cls.__create == nil,
string.format("class() - create class \"%s\" with more than one creating function or native class",
classname));
cls.__create = function() return super:create() end
else
-- super is pure lua class
cls.__supers = cls.__supers or {}
cls.__supers[#cls.__supers + 1] = super
if not cls.super then
-- set first super pure lua class as class.super
cls.super = super
end
end
else
error(string.format("class() - create class \"%s\" with invalid super type",
classname), 0)
end
end cls.__index = cls
if not cls.__supers or #cls.__supers == 1 then
setmetatable(cls, {__index = cls.super})
else
setmetatable(cls, {__index = function(_, key)
local supers = cls.__supers
for i = 1, #supers do
local super = supers[i]
if super[key] then return super[key] end
end
end})
end if not cls.ctor then
-- add default constructor
cls.ctor = function() end
end
cls.new = function(...)
local instance
if cls.__create then
instance = cls.__create(...)
else
instance = {}
end
setmetatableindex(instance, cls)
instance.class = cls
instance:ctor(...)
return instance
end
cls.create = function(_, ...)
return cls.new(...)
end return cls
end

原理就不细说了。改动__index。使得在訪问其成员的时候能遍历全部的supers父类去查找该成员(类似js里的原型链,但那是一条链,这里lua可自由发挥)。

他的第一个參数是类名,后面的參数能够是父表或者函数,函数的话仅仅能有一个,是用来作为创建函数的__create,会在.new的时候被调用。

用法:

local UIScene = class("UIScene")
UIScene.__index = UIScene function UIScene.extend(target)
local t = tolua.getpeer(target)
if not t then
t = {}
tolua.setpeer(target, t)
end
setmetatable(t, UIScene)
return target
end function UIScene.create()
local scene = cc.Scene:create()
local layer = UIScene.extend(cc.Layer:create())
layer:init()
scene:addChild(layer)
return scene
end

getpeer/setpeer我还不是非常理解,从网上找到说明留着消化:

Those are tolua functions. The tolua manual (for example here) has explanations for them.

tolua.setpeer (object, peer_table) (lua 5.1 only)
Sets the table as the object's peer table (can be nil). The peer table is where all the custom lua fields for the object are stored. When compiled with lua 5.1, tolua++ stores the peer as the object's environment table, and uses uses lua_gettable/settable (instead of lua_rawget/set for lua 5.0) to retrieve and store fields on it. This allows us to implement our own object system on our table (using metatables), and use it as a way to inherit from the userdata object. Consider an alternative to the previous example:
-- a 'LuaWidget' class
LuaWidget = {}
LuaWidget.__index = LuaWidget function LuaWidget:add_button(caption)
-- add a button to our widget here. 'self' will be the userdata Widget
end local w = Widget()
local t = {}
setmetatable(t, LuaWidget) -- make 't' an instance of LuaWidget tolua.setpeer(w, t) -- make 't' the peer table of 'w' set_parent(w) -- we use 'w' as the object now w:show() -- a method from 'Widget'
w:add_button("Quit") -- a method from LuaWidget (but we still use 'w' to call it)
When indexing our object, the peer table (if present) will be consulted first, so we don't need to implement our own __index metamethod to call the C++ functions.
tolua.getpeer (object) (lua 5.1 only)
Retrieves the peer table from the object (can be nil).

lua——元表、元方法、继承的更多相关文章

  1. 【quick-cocos2d-x】Lua 面向对象(OOP)编程与元表元方法

    版权声明:本文为博主原创文章,转载请注明出处. 面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物. 早期的计算机编程是基于面向过程的方法,通过设计一个算法就可以解决当时 ...

  2. Lua __index元方法

    [Lua __index元方法] 当你通过键来访问 table 的时候,如果这个键没有值,那么Lua就会寻找该table的metatable(假定有metatable)中的__index 键.如果__ ...

  3. Lua的元方法__newindex元方法

    上一篇介绍了__index元方法,总结来说:__index元方法是用于处理访问table中不存在的字段时的情况. 而今天,介绍的__newindex元方法,总结来说,就是:用于处理给table中不存在 ...

  4. lua编程之元表与元方法

    一. 前言 lua是一种非常轻量的动态类型语言,在1993年由由Roberto Ierusalimschy.Waldemar Celes 和 Luiz Henrique de Figueiredo等人 ...

  5. lua metatable和metamethod元表和元方法

    Lua中提供的元表是用于帮助Lua数据变量完成某些非预定义功能的个性化行为,如两个table的相加.假设a和b都是table,通过元表可以定义如何计算表达式a+b.当Lua试图将两个table相加时, ...

  6. lua元表(metatable)和元方法(metamethod)

    (一) 元表概念: 引言:Lua中的每个值都有一套预定义的操作集合,如数字相加等.但无法将两个table相加,此时可通过元表修改一个值的行为,使其在面对一个非预定义的操作时执行一个指定操作. 访问机制 ...

  7. Lua 学习笔记(十一)元表与元方法

    在Lua中的每个值都有一套预定义的操作集合.例如可以将数字相加,可以连接字符串,还可以在table中插入一对key-value等.但是我们无法将两个table相加,无法对函数作比较,也无法调用一个字符 ...

  8. lua元表与元方法

    lua中提供的元表(metatable)与元方法(metamethod)是一种非常重要的语法,metatable主要用于做一些类似于C++重载操作符式的功能. lua中提供的元表是用于帮助lua变量完 ...

  9. lua元表和元方法 《lua程序设计》 13章 读书笔记

    lua中每个值都有一个元表,talble和userdata可以有各自独立的元表,而其它类型的值则共享其类型所属的单一元表.lua在创建table时不会创建元表. t = {} print(getmet ...

随机推荐

  1. :Windows下RabbitMQ安装及入门

    1.Windows下安装RabbitMQ需要以下几个步骤 (1):下载erlang,原因在于RabbitMQ服务端代码是使用并发式语言erlang编写的,下载地址:http://www.erlang. ...

  2. JavaScript事件代理和事件委托

    一.概述: 那什么叫事件委托呢?它还有一个名字叫事件代理,JavaScript高级程序设计上讲:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件.那这是什么意思呢?网上的 ...

  3. scala 学习笔记八 简洁性

    Scala可以简洁地表示概念,有时甚至可以说过于简洁. 1.消除中间结果 在组合表达式中,最后一个表达式会变成整个表达式的结果.下面的例子中,值会被捕获到val result中,然后result从方法 ...

  4. maven编译报错 -source 1.7 中不支持 lambda 表达式

    Maven项目编译失败: [ERROR] COMPILATION ERROR : [INFO] ---------------------------------------------------- ...

  5. 【Docker】基于docker+etcd+confd + haproxy构建高可用、自发现的web服务

    各个工具介绍 (1)Docker:Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux机器上,也可以实现虚拟化,docker ...

  6. Android-Bundle认知、和Intent的差别

    不时的回过头来看看自己的Andriod学习.实践之路,总发现有些曾经不明确的,如今清楚缘由.也会发现一些之前没怎么关注的.如今看到了 ,很想去深刻了解的. 比方:Bundle. 在一个Activity ...

  7. 自定义cas客户端核心过滤器AuthenticationFilter

    关于cas客户端的基本配置这里就不多说了,不清楚的可以参考上一篇博文:配置简单cas客户端.这里是关于cas客户端实现动态配置认证需要开发说明. 往往业务系统中有些模块或功能是可以不需要登录就可以访问 ...

  8. IIS 之 连接数、并发连接数、最大并发工作线程数、队列长度、最大工作进程数

    一.IIS连接数 一般购买过虚拟主机的朋友都熟悉购买时,会限制IIS连接数,顾名思义即为IIS服务器可以同时容纳客户请求的最高连接数,准确的说应该叫“IIS限制连接数”. 客户请求的连接内容包括: [ ...

  9. cybergarage-upnp

    官网: http://www.cybergarage.org/twiki/bin/view/Main/UPnPFramework Open Source Frameworks for UPnP Cyb ...

  10. php之phpstorm入门

    入门篇!见这章