일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 비교 함수 객체
- 루아
- 메타테이블
- 다형성
- 영화
- 게임
- 언리얼
- exception
- resource management class
- 오블완
- c++
- virtual function
- effective stl
- 반복자
- operator new
- 참조자
- Effective c++
- 스마트 포인터
- 암시적 변환
- more effective c++
- implicit conversion
- 예외
- 상속
- 영화 리뷰
- lua
- 함수 객체
- 티스토리챌린지
- UE4
- Smart Pointer
- reference
- Today
- Total
스토리텔링 개발자
[Lua] 상속 구조 만들기 본문
개요
루아에는 상속이라는 개념이 없습니다.
정확하게 말하자면, 언어에서 지원하지 않는다는 의미입니다.
하지만 클래스를 통한 객체 지향 프로그래밍에 익숙하다면 상속 개념을 사용하고 싶은 것도 사실입니다.
이에 대해서는 여러가지 방법이 있겠지만,
여기선 메타테이블을 사용하여 상속 개념을 구현하는 방법을 하나 소개하겠습니다.
주요 루아 함수
상속 개념을 구현하기 위해서 아래의 루아 함수들을 활용합니다.
rawget
메타 테이블 콜스택을 거치지 않고 해당 테이블의 값을 직접 가져옵니다.
rawset
메타 테이블 콜스택을 거치지 않고 해당 테이블에 키 / 값 페어를 직접 적용합니다.
setmetatable(t, mt)
mt 테이블을 t 테이블의 메타 테이블로 설정합니다.
getmetatable(t)
t 테이블의 메타 테이블을 가져옵니다. 없으면 nil을 리턴합니다.
메타 테이블에 관련해서는 아래의 글을 참고해 주세요.
상속 구조 만들기
-- 상속 구조 만들기 함수
function setParent(parent, child)
setmetatable(child, parent); -- 메타테이블을 부모로
parent.__index = function(t, k)
local findParent = getmetatable(t)[k]; -- 메타테이블의 인덱스 검색
if findParent ~= nil then
return findParent;
end
return rawget(t, k); -- 없다면 메타테이블 호출을 배제한 본인 테이블의 키값 탐색
end
end
-- t1(grandParent)
t1 = {}
t1.grandParentPrint = function()
print("grandParent");
end
-- t2(parent) : t1을 상속받는 테이블
t2 = {}
t2.parentPrint = function()
print("parent");
end
setParent(t1, t2);
-- t3 : t2를 상속받는 테이블
t3 = {}
setParent(t2, t3);
-- 함수 호출 테스트
t3.grandParentPrint();
t3.parentPrint();
출력 결과
grandParent
parent
setParent 내부 로직
상속 구조 만들기를 재사용할 수 있도록 setParent 함수를 정의하였습니다.
함수 내에서는 아래 순서를 따라 상속 구조가 만들어집니다.
1. 자식 테이블의 메타테이블로 부모 테이블을 셋팅
- setmetatable(child, parent)
2. 부모 테이블의 __index 함수 재정의
부모 테이블이 자식 테이블의 메타테이블이 되는 형태를 취하고 있습니다.
이 구조는 getmetatable()을 통해서 부모 테이블 자체를 가져올 수 있다는 장점이 있습니다.
보시다시피 재정의한 __index 내부에서도 getmetatable()을 통해 부모를 가져와 활용하고 있습니다.
__index 내부 로직
key를 통해 value 값을 가져오는 기능을 재정의합니다.
재정의한 기능은 아래의 흐름으로 동작합니다.
1. 부모의 키값을 탐색(메타테이블 콜스택을 통하는 기본 탐색)
2. 부모에게 값이 없을 경우, 자식(자신)의 키값을 탐색(메타테이블 콜스택 없이 순수하게 자신의 키값만 탐색)
1번 과정을 통해서 몇 단계의 부모들이 있더라도 그 상위의 부모 테이블들을 모두 탐색할 수 있습니다.
왜냐하면 부모 테이블의 __index 기능도 재정의 되어 있기 때문입니다.
계속해서 부모 테이블을 탐색해 나가는 구조가 됩니다.
1번에서 부모(들)에 매칭되는 키값이 없다면 그때서야 본인 내부를 탐색합니다.(2번 과정)
이때는 순수히 본인 테이블의 내부만을 확인하기 위해 rawget() 함수를 사용합니다.
'개발 > Lua' 카테고리의 다른 글
[Lua] __newindex 로 할당 로직 재정의 (0) | 2021.08.06 |
---|---|
[Lua] 메타 테이블(Metatable) (0) | 2021.07.21 |