2012-11-21 2 views
-1

서로를 참조하는 여러 관리되지 않는 C++ 클래스가 있습니다. 인스턴스가 해제 될 때 포인터가 매달리지 않도록하려면 주로 스마트 포인터를 boost_ptr으로 사용하고 있습니다. 여태까지는 그런대로 잘됐다.관리되는 C++ 래퍼에 매달린 포인터

그러나 C++/CLI의 래퍼도 있습니다. 관리되지 않는 거의 모든 관리되지 않는 클래스에는 .NET 응용 프로그램에 노출되는 해당 관리되는 클래스가 있습니다. 래퍼는 꽤 간단하지만 안전하지 않은 포인터를 사용하여 ManagedClass에서 UnmanagedClass *를 참조해야했습니다. CLR은 관리되지 않는 유형을 클래스 멤버 (포인터 만 해당)로 지원하지 않기 때문에 boost :: shared_ptr을 ManagedClass의 멤버로 사용할 수 없습니다.

예 : 클래스 휠의 4 개의 인스턴스를 포함하는 클래스 Car. 5 개의 관리되지 않는 인스턴스 각각에는 5 개의 관리되는 동일한 인스턴스가 있습니다. 비 관리 차는 바퀴를 변경해야 할 수도 있고, 관리되지 않는 휠의 인스턴스 4 개를 삭제하고 새로운 4 개의 인스턴스를 삭제할 수 있습니다. Managed Car는 새 관리되지 않는 Wheel에서 4 개의 Managed Wheel 인스턴스를 생성하도록 요청합니다.

그러나 Wheel의 4 개의 이전 관리 인스턴스는 관리되는 영역에서 여전히 범위에 있으며 이제 이전 관리되지 않는 인스턴스에 대한 매달린 포인터를 포함합니다. 래퍼의 원시 동등 물이 폐기되었다는 것을 인식하는 방법에 대한 아이디어가 있습니까? 스마트 포인터를 사용한 쉬운 작업. 관리 코드로 사용할 수 있습니까?

답변

0

왜 내부 인스턴스 카운팅을 사용하지 않습니까? 그런 다음

class Base 
{ 
    int refCount = 0; 

public: 
    void AddRef() { refCount++; } 
    void Release() { refCount--; if (refCount == 0) delete this; } 
} 

이 모두를위한 기본 클래스로 사용하고 더 이상에 (예를 들어 그것을 필요로하지 않을 때) 당신이 클래스와 릴리스 (의 인스턴스를 취득 할 때 AddRef에 전화를 기억 : 기본 기본 클래스를 만듭니다 폐물 소각로). C++/CLI 클래스에서 동일한 작업을 수행해야합니다. IDisposable 인터페이스를 구현하고 Dispose() 메서드에서 보관 된 네이티브 클래스 인스턴스를 정리합니다. AddRef를 생성자 내부에서 한 번 호출하고 소멸자/Dispose 내부에서 한 번만 릴리스해야하기 때문에 사용하는 것이 문제가되지 않습니다.

+0

shared_ptr 스마트 포인터를 사용하여 원시 코드에서 이미 refcount를 유지하고 있습니다 (부스트가 나를 위해이 작업을 수행하고 있습니다). 물론 나는 다른 수를 시작할 수 없다. 내 문제는 내가 같은 부스트 ​​:: shared_ptr 네이티브 C + + C++에서 사용할 수 없습니다/cli (또는 어떻게 그림 밖으로 그림). CLR은 관리되지 않는 형식을 클래스 멤버 변수로 지원하지 않습니다. boost :: shared_ptr 이 아닌 NativeClass *에 대한 포인터를 가질 수 있습니다. –

+0

그리고 정확하게 boost :: shared_ptr을 사용하는 대신 참조 계산 메커니즘을 직접 구현하는 것이 좋습니다. 이 방법을 사용하면 항상 Managed 코드에서 Release()를 호출 할 수 있습니다. 도움을 주신 덕분에 – Spook

+0

. 그러나 이것은 어떻게 매달려있는 포인터 문제를 해결할 수 있습니까? 릴리스()가 네이티브 코드 자체 (관리되는 코드가 아닌)에서 호출되고 refCount가 0이되면이 코드를 삭제한다고 가정 해 보겠습니다. 네이티브 코드는 괜찮습니다. 그러나 관리되는 상대방은 여전히 ​​삭제 된 기본 클래스에 매달린 참조를 가지고 있습니다. –