为什么Lua需要元词?

时间:2017-04-10 20:13:20

标签: c++ oop lua

我是一名学习Lua的C ++程序员,试图理解为什么需要getmetatable()和setmetatable()。

根据所有教程,如果我想在我的子类定义中的某个地方从“基类”(使用C ++概念)创建一个“子类”,我会有这样的东西:

1) setmetatable(subclass, getmetatable(baseclass)) 

但为什么呢?为什么不这样做:

2) setmetatable(subclass, baseclass)

或者为什么不将所有基类成员复制到子类中并使用元数据进行修改?

3) for k,v in pairs(baseclass) do
    subclass[k] = v 
end

毕竟,OOP在概念上,我所要做的就是让我的子类成为一种基类,然后添加一些差异。所以我先从基类的副本开始,然后做我的修改,使我的子类不同。

然后我突然意识到,也许metatables是共享实例。也就是说,具有相同元表的类共享内存中完全相同的元表。是对的吗?如果我在单个元表中更改数据元素,那么具有该元表的所有表都将经历相同的数据更改?如果我在metatable中有一个“counter”变量并将其递增,那么使用该metatable的所有类都将使该成员变量递增。

这就是所有教程中都没有明确的区别,以及是什么让metatable如此混乱。因此,用C ++术语来说,元数据是共享它们的类的静态成员。

但是上面的方法3仍然可以实现目标但是浪费,因为它创建了基类成员的副本而不是共享它们。

那么,这是一个创建子类的有效函数吗? (复制基类然后添加新成员以使其与基类不同)

local Developer = subclass(Person, { skillz = {"c++", "lua", "python"}})

function subclass(base, new_members)
    local self = {}
    setmetatable(self, getmetatable(base))
    local mt = getmetatable(self)
    for k,v in pairs(base) do -- replicate bases members that aren't in its metatable into us as our metatable
        mt[k] = v
    end
    for k,v in pairs(new_members) do  -- add new members or overrides that make us different than base!
        mt[k] = v
    end
    return self
end

0 个答案:

没有答案