【元表】

元表中的键为事件(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. HDU OJ Digital Roots 题目1013

     /*Digital Roots Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  2. RHEL7系统修复rm -rf /boot /etc/fstab

    RHEL7/Centos7系统发布这么长时间了,大家都知道这个系统的一个特点就是用systemctl代替了init系统守护进程,系统越来越模块化了.在新版的系统中许多的命令也发生了改变,grub也变为 ...

  3. MySQL 动态sql语句运行 用时间做表名

    1. 描写叙述 在使用数据的时候,我时候我们须要非常多数据库,并且想用时间来做表名以区分.可是MySQL在存储过程中不支持使用变量名来做表名或者列名. 比方,有一个表我们想以"2015-07 ...

  4. leetcode第一刷_Integer to Roman

    这道题当时不会写,是參照discuss写的. 首先要弄明确罗马数字的规则,这个在国外难道是常识吗.为什么题干一点都没讲.. 4000以下一共同拥有以下几种符号:"M", " ...

  5. AutoPlay Menu Builder入门教程

    1 拖动窗口可以设置主界面的窗口大小,在下面有版面预览 2 常用东西介绍.右侧的素材库除了按钮还有图像,背景,音乐等.使用按钮的时候选中需要的按钮样式,双击即可上屏.图形按钮即使可以使用图像作为背景的 ...

  6. windows下的虚拟内存分配分析

    让我们从原始的进程创建开始分析吧.当进程创建后,操作系统给该进程分配4GB的虚拟地址空间,这部分虚拟内存是你的应用程序看的到的区域(注意很大一部分是不能访问的,比如:内核区域,这部分加载了操作系统中的 ...

  7. 把Linux目录挂载到开发板、设置开发板从NFS启动、取消开发板从NFS启动

    声明:文中"PC虚拟机Linux"是指在PC上安装了虚拟机,然后在虚拟机中装的Linux. 关于NFS的详细介绍可参考:http://www.cnblogs.com/nufangr ...

  8. PyQt5教程——布局管理(4)

    PyQt5中的布局管理 布局管理是GUI编程中的一个重要方面.布局管理是一种如何在应用窗口上防止组件的一种方法.我们可以通过两种基础方式来管理布局.我们可以使用绝对定位和布局类. 绝对定位 程序指定了 ...

  9. 3DMax脚本插件--改动材质&amp;贴图名称

    从网上淘到了一套人物的模型,当时的心情是激动无比,掏出用的不熟练的3DMax折腾了半天.突然发现了一个蛋疼的事儿,所有的模型文件,材质名称,子材质,以及贴图所实用的是中文命名!! ! 尽管说是能跑,只 ...

  10. zookeeper技术浅析

    Zookeeper是hadoop的一个子项目,尽管源自hadoop,可是我发现zookeeper脱离hadoop的范畴开发分布式框架的运用越来越多. 今天我想谈谈zookeeper.本文不谈如何使用z ...