2012-02-23 3 views
8

Direct3D를 C++로 사용할 때 "ID3D11Buffer * vertexBuffer_"가 포함 된 "Cube"클래스를 작성할 수 있으며 해당 Cube 객체의 소멸자가 vertexBuffer _-> Release()를 호출하는지 확인할 수 있습니다.D 언어로 리소스 확보

"unique_ptr cube_"객체가 포함 된 "Scene"클래스를 가질 수 있습니다. 따라서 장면을 삭제하면 큐브가 삭제되고 결과적으로 사용중인 D3D 리소스에 대한 릴리스가 호출된다는 것을 알았습니다.

D에서 할 수 없습니다. 소멸자를 쓸 수는 있지만 언제 호출 될지는 모르겠습니다. GC가 메모리를 필요로하지 않는다면 결코 호출되지 않을 것입니다 ...

그래서 D에서 이런 종류의 것을 처리하는 가장 좋은 방법은 무엇입니까? "Free"멤버 함수를 각 객체에 추가하여 소유하고있는 모든 객체에서 자체 리소스를 호출하고 "Free"를 호출하지만 오류가 발생하기 쉬운 수동 작업과 C++에서 한 걸음 뒤로 물러납니다.

D에서 이런 종류의 작업을 처리하는 더 좋은 방법이 있습니까?

답변

6

스택에 구조체를 사용할 수 있습니다. 에는 결정 론적 파괴가 있습니다. std.typecons.RefCounted을 사용하여 참조 수를 계산할 수도 있습니다. 소멸자가 실행되도록 보장하려면 힙에 구조체를 사용하지 마십시오. 현재 GC에서 필요한 정보가 없기 때문에 struct의 소멸자가 힙에 배치되면 실행되지 않는다고 생각하지 않습니다. 미래.). 당신이 수업 시간에 힙에 그것을 퍼팅 주장, 당신은 명시 적으로 객체를 파괴하려는 경우

그러나, 당신은 그것을 clear를 호출 할 수

clear(obj); 

객체의 소멸자를 호출 것이다 그 다음 그것을 무효 상태에 넣고, 그 후에 그것을 사용하려고 시도하는 모든 것은 폭발해야합니다 (IIRC, 가상 테이블은 제로가됩니다). 그러나 메모리는 실제로 해제되지 않습니다. 그것이 GC의 일입니다. delete을 사용하지 마십시오. 그것은 더 이상 사용되지 않을 것입니다. 나는 나이가 들었을 때 그것을 없애기 위해 계획 되었기 때문에 실제로 아직 놀지 않았다는 것에 놀랍니다.

물론 하나의 옵션은 리소스를 해제하기 위해 호출하는 명시 적 기능을 갖는 것입니다. 그것이 좋은 생각인지 아닌지는 당신이하는 일에 달려 있습니다. 그러나 관계없이 수업은 GC에 의해 수집되도록되어 있으며 언제든지 선택할 수 있습니다.

커스텀 할당 자에 대한 작업이 진행되고 있습니다. 클래스를 할당하는 방법에 대한 더 많은 옵션을 제공하며, 그 중 하나는 클래스의 결정 론적 파괴를 허용하지만, 아직 준비가되지 않았습니다.

그리고 당신은 미친 느낌이 있다면, 당신은 (scope이 다른 상황에서 주변에 집착하지만 - 같은 scope로 문) 곧 중단 될 수있는 유형 수정 scope을 대체 std.typecons.scoped를 사용할 수 있습니다. 그것은 스택에 클래스를 둡니다.그러나 그것은 안전하지 않습니다 (따라서 scope은이 컨텍스트에서 벗어날 것입니다). 스택에 객체를 고정하려고한다면 구조체를 사용할 수도 있습니다.

편집 : 당신은 또한 당신이 C++에있는 것처럼 메모리 덩어리를 할당 비 GC에서 개체를 넣어 mallocstd.conv.emplacefree을 사용할 수 있습니다,하지만 난 당신이 명시 적으로 호출 할 거라고 생각 free은 소멸자 (C 함수)에 대해 이해하지 못하기 때문에 소멸자가 실행되도록해야합니다. 그걸로 메모리를 없애 버릴 수 있다는 장점이 있습니다 (GC 힙의 객체에 clear을 사용하면 객체의 내용을 파괴하고 메모리를 비우지 않을 것입니다).하지만 그게 많이 산다는 것을 모릅니다. GC 할당 객체에 clear을 사용합니다.

그러나, 당신은 당신을위한 mallocemplace을 수행 new 유사한 무료 함수를 만들 수 있고, 당신에게 C와 같은 상황을 줄 것 소멸자와 free를 호출 delete 유사한 무료 기능을 가지고 ++ . 실제로 표준 라이브러리에 넣을 수있을만큼 유용할지 궁금합니다. 그것은 아마 사용자 지정 할당 자로 끝날 것 같은 종류의 일입니다. 따라서, 상대적으로 가까운 미래에, 당신은

auto obj = customAllocObj.create!MyObj(args); 
//Do stuff... 
customAllocObj.destroy(obj); 

처럼 뭔가를 사용자 지정 할당을 사용할 수 있다면 전혀 놀랍지 않을 것이다 그리고 나는이 상당히 잘 즉 본질적으로의 주어진 문제를 해결할 것이라고 생각 당신이 C++에서 가지고있는 것과 똑같은 것, 내장 된 newdelete이 아니라 라이브러리 함수를 가지고있는 것입니다. 나는 그것을 뉴스 그룹에 올릴 것이라고 생각한다. 그러한 기능을 원하는 사람들이 적어도있을 것이라고 기대합니다. 그리고 그것은 맞춤 할당 자와 잘 어울리는 것 같습니다.

+0

포괄적 인 답변에 감사드립니다. 개체의 수명이 오래 걸리므로 스택에서 구조체를 사용할 수 있는지 잘 모르겠습니다. 분명히 나를 위해 일할 수도 있지만 내 자신의 clear() 함수와 다른 것 같지 않습니다. Ypu는 나에게 생각할 것들을 더 많이주었습니다 :) – jcoder

+0

@ JohnB 나는 구조체를 지나가고 있다고 가정하고 있었지만 상황에 따라서는 작동하지 않을 수도 있습니다. 자신 만의 함수를 사용한다면 소멸자를 호출하지 말 것을 권하는 것입니다. 단지 문제를 요구하는 것입니다. 소멸자가 함수를 호출하여 리소스를 해제 할 수는 있지만 호출 할 수는 있습니다. 따라서 소멸자를 실제로 호출하려면 'clear'를 사용하십시오.당신이 원하는 것은 리소스를 없애는 것뿐이라면, 객체를 파괴하는 것보다는 그것을 위해 특별히 다른 함수를 호출하는 것이 더 합리적 일 것입니다. 코드에 따라 다릅니다. –

2

명확히하기 위해 : 소멸자는 이며 항상이라고합니다. 응용 프로그램이 종료 될 때까지 개체가 완료되지 않은 경우 GC는 해당 finalizer를 실행합니다.

free() 함수를 호출하여 버텍스 버퍼를 수동으로 호출하는 것이 C++에서 수동으로 메모리를 관리하는 것보다 오류가 발생하는 것을 쉽게 볼 수는 없습니다. 어쨌든 다음과 같이 보길 원할 수 있습니다. http://www.dlang.org/phobos/std_typecons.html#scopedhttp://www.dlang.org/phobos/std_typecons.html#RefCounted

+2

문제는 메모리가 해제 될 때 소멸자가 호출되는데, GC가 더 이상 객체를 더 이상 참조하지 않는다는 사실을 발견 할 때 어느 시점에있을 것입니다. 나는 D3D 객체가 미래에 어떤 정의되지 않은 점이 아니라 즉시 풀려나는 것이 필요하다 ... – jcoder

+0

['delete'] (http://www.d-programming-language.org/expression.html#DeleteExpression)? "UnaryExpression이 클래스 객체 참조이고 해당 클래스의 소멸자가 있으면 해당 객체 인스턴스에 대해 소멸자가 호출됩니다." –

+0

'delete'가 언어에서 제거되고 있습니다. 사용하지 마십시오. 객체의 소멸자를 호출하고 객체를 무효화하는'clear'을 사용할 수 있지만 메모리를 해제하지는 않습니다. 그것이 GC의 일입니다. 결정적 파괴를 원한다면 구조체를 사용하십시오. –