0

私はLuaを学ぼうとしているので、これが簡単に答えられる質問であることを願っています。次のコードは機能しません。変数childContextは、クラスのすべてのインスタンス間でリークします。

--[[--
Context class.
--]]--
CxBR_Context = {}

-- Name of Context
CxBR_Context.name = "Context Name Not Set"

-- Child Context List
CxBR_Context.childContexts = {}

-- Create a new instance of a context class
function CxBR_Context:New (object)
  object = object or {} -- create object if user does not provide one
  setmetatable(object, self)
  self.__index = self
  return object
end

-- Add Child Context
function CxBR_Context:AddChildContext(context)
  table.insert(self.childContexts, context)
  print("Add Child Context " .. context.name .. " to " .. self.name)
end


--[[--
Context 1 class. Inherits CxBR_Context
--]]--
Context1 = CxBR_Context:New{name = "Context1"}


--[[--
Context 1A class.Inherits CxBR_Context
--]]--
Context1A = CxBR_Context:New{name = "Context1A"}


--[[--
Context 2 class.Inherits CxBR_Context
--]]--
Context2 = CxBR_Context:New{name = "Context2"}


--[[--
TEST
--]]--
context1  = Context1:New() -- Create instance of Context 1 class
print(context1.name .." has " .. table.getn(context1.childContexts) .. " children")
context2  = Context2:New() -- Create instance of Context 2 class
print(context2.name .." has " .. table.getn(context2.childContexts) .. " children")
context1A = Context1A:New() -- Create instance of Context 1A class
print(context1A.name .." has " .. table.getn(context1A.childContexts) .. " children")

context1:AddChildContext(context1A) -- Add  Context 1A as child to context 1

print(context1.name .." has " .. table.getn(context1.childContexts) .. " children") -- Results Okay, has 1 child
print(context2.name .." has " .. table.getn(context2.childContexts) .. " children") -- Why does thin return 1, should be 0

リークしているオブジェクト指向のluaクラスを見ると、コンストラクター関数を次のように変更することで問題を修正できます。

-- Child Context List
-- CxBR_Context.childContexts = {}

-- Create a new instance of a context class
function CxBR_Context:New (object)
  object = object or { childContexts = {} } -- create object if user does not provide one
  setmetatable(object, self)
  self.__index = self
  return object
end

だから私の質問は:

  1. 最初の例のように、クラス変数を宣言するためのよりクリーンな方法があるので、コンストラクターに含める必要はありませんか?
  2. CxBR_Context.nameが機能するのに、テーブルCxBR_Context.childContextsが機能しないのはなぜですか?
4

2 に答える 2

1
  1. いいえ、そうは思いません。作成する各子Contextオブジェクトに、独自のchildContextsフィールドを持たせる必要があります。

  2. 名前フィールドを含むテーブルをNew関数に渡すため、これは機能します。ここで行ったことは次のとおりです。

Context1 = CxBR_Context:New {name = "Context1"}

  • フィールド「name」が「C​​ontext1」に設定されたテーブルを作成します
  • テーブルをコンストラクターに渡します
  • [コンストラクター内]最初のステップで作成したテーブルにメタテーブル(元のCxBR_Contextテーブル)を割り当てます。

したがって、基本的に、Context1.nameを呼び出すときは、コンストラクターを呼び出すときに作成したContext1テーブルからフィールドを取得します。ただし、childContextを使用してインデックスを作成し、そのようなフィールドが存在しない場合(コンストラクターの段階では「名前」フィールドのみを作成したため)、LuaはCxBR_Contextである__indexテーブルを調べます。そして、このテーブルはすべてのContextXオブジェクトに共通です。

編集:

object = object or { childContexts = {} } -- create object if user does not provide one

実際には、次のように独自のテーブルを指定した場合、これも機能しません。

Context1 = CxBR_Context:New{name = "Context1"}

オブジェクト引数がnilの場合、つまり、selfパラメーターだけでコンストラクターを呼び出す場合にのみ機能します。

于 2013-03-27T07:48:04.000 に答える
0

1.
を使用することにより、このメンバーが存在する最も近いスーパークラスのメンバーであることが判明する、がtable.insert(self.member, v)指すコンテナーのコンテンツを変更します。 サブクラスのメンバーに値を割り当てる必要がある場合は、明示的に割り当ててください。使用する self.member

-- create a copy of array with one additional element
self.childContexts = { context, unpack(self.childContexts) }

それ以外の

table.insert(self.childContexts, context)

2.
に割り当てをCxBR_Context.name使用していて、に使用していないためCxBR_Context.childContexts

于 2013-03-27T07:47:59.227 に答える