1

次のようなシンプルなクラスのシンプルな Lua ゲーム:

creature = class({ 
name = "MONSTER BADDY!",

stats = { power = 10, agility = 10, endurance = 10, filters = {} },

other_things = ...
})

creatureA = creature.new()

creatureB = creature.new()

creatureA.name = "Frank"

creatureB.name = "Zappa"

creatureA.stats.agility = 20

creatureB.stats.power = 12

- 何とか何とか何とか

非テーブル値はインスタンスごとに個別ですが、テーブル値はすべてのインスタンス間で共有されます。1 つのインスタンスで stats.X 値を変更すると、他のすべてのインスタンスに同じ統計テーブルが表示されます。

Q1: OO の実装に欠陥がありますか? LOOP を試してみましたが、同じ結果が得られました。私のロジックに根本的な欠陥がありますか?

Q2: クリーチャーの各インスタンスに独自の統計テーブル (およびサブ テーブル) を持たせるにはどうすればよいですか?

PS。例よりも少し複雑で、コードの他の部分がこのネストされたテーブルの実装で単純化されているため、クラス テーブルをフラット化することはできません。

4

4 に答える 4

3

classLuaの標準機能ではありません。ロベルトから借りたのか、自分で転がしたのか、それとも何なのかはわかりません。しかし、私の推測では、newメソッドを変更して、浅いコピーではなく、プロトタイプの深いコピーを実行するようにします。

function deep_copy(v)
  if type(v) == 'table' then
    local u = { }
    for k, v in pairs(v) do
      u[k] = v
    end
    setmetatable(u, getmetatable(v))
    return u
  else
    return v
  end
end

(アラート:このコードをコンパイルすることはもちろん、実行することも試みていません。)

于 2010-05-30T20:59:59.437 に答える
3

クラスインスタンスにはメタテーブルのように設定されたクラステーブルがあるため、そのように機能します(__indexまあ、ほとんどの実装はそのように機能します)。Lua 5.1 Reference Manual: Metatablesを読む必要があるかもしれません。creatureA.statsstatscreatureA__indexcreature.stats

クラスのテーブル コンストラクターでインスタンスごとの変数を宣言することはできません (クラス テーブルからインスタンスにすべてをディープ コピーしない限り、非常にコストがかかります)。

クラスの実装で使用する初期化関数でそれを行う必要があります。

creature = class
{
     __init = function(self, ...)
         self.stats = {power = 10, agility = 10, endurance = 10, filters = {}}
     end,
}
于 2010-05-30T10:20:26.270 に答える
0

新しいテーブルを作成するときに、共有したくない場合creatureはいつでも新しいテーブルを作成できます。stats

creature = class({ 
    name = "MONSTER BADDY!",
    stats = stats.new({ power = 10, agility = 10, endurance = 10, filters = {} }),
    other_things = ...
})

パワー、敏捷性などは、のコンストラクターの引数として渡されますstats

于 2010-05-30T09:58:13.427 に答える
0

クラスと呼ばれるあなたのその機能は 疑わしいようです。私は可能な限り単純なコードを選びます。これがモンスタークラスファイルです。派手なことは何もありませんし、毛羽立ちがないと言う人もいますが、少なくとも来週は自分でコードを読むことができます。

-- Class object

monster = {}
monster.__index = monster

-- Class methods

function monster.new(name)
    local o = {}
    o.name = name
    o.stats = {power = 10, agility = 10, endurance = 10, filters = {}}
    setmetatable(o, monster)
    return o
end

function monster:shout()
    print('Aaaaaaa! My name is ' .. self.name .. '!')
end

そしてここに出力があります:

> lua
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> require 'monster'
> m = monster.new('Katla')
> m:shout()
Aaaaaaa! My name is Katla!
于 2010-05-31T14:44:10.427 に答える