C++/CLI Type
Programming/C++/CLI / 2010. 9. 13. 17:43
■ C++/CLI Data Type
C++/CLI 는 3가지 데이터 타입을 가지고 있다.
- Refercence Type
- Value Type
- Native Type
Native Type
C++ 이 가지고 있는 타입으로써 int, float, class, struct, 등이 있다.
타입 인스턴스의 메모리는 스택에 할당된다.
new 연산자로 동적 메모리 생성 하면 힙에 할당 된며, 메모리 해제는 프로그래머의 책임이다.
Value Type & Reference Type
Managed 환경의 Data Type 으로 모두 System::Object 클래스로 부터 상속받아 구현된다.
System::Object 가 외부로 노출시킨 메소드는 다음과 같다.
Method Name | Return Value | Accssibility |
Equals | bool | public |
GetType | Type | public |
ToString | System::String^ | public |
GetHashCode | int | public |
Finalize | - | protected |
MembewiseClone | System::Object^ | protected |
ReferenceEquals | bool | public static |
Value Type 은 System::ValueType 으로 부터 상속 받는다. System::ValueType 은 System::Object 를 상속 받는다. Value Type 은 메모리를 항상 스택에 할당한다. 모든 Primitive Data Type 과 Struct 들은 Value Type 이다.
■ Primitive Types Mapping
Data Type Name | Type | C++/CLI Keyword |
16bit Integer | System::Int16 | short |
32bit Integer | System::Int32 | int |
64bit Integer | System::Int64 | __int64, long long |
Double | System::Double | double |
Character [2 bytes] | System::Char | char |
Character [1 byte] | System.Byte | byte |
Boolean | System.Boolean | bool |
※ 이 밖에도 많은 타입이 정의되어 있다.
※ Primitive Type 은 Value Type 으로서 Stack 에 메모리 할당 된다.
※ Native Code 와 C++/CLI 간의 Primitive Type 값 변환은 별도의 조작없이 바로 해주면 된다.
Primitive Type 의 선언과 사용 예
C++/CLI 에서 Primitive Data Type 은 Value Type 으로서 .NET 의 Primitive Data Type 을 사용하는 방법과 동일하다.
■ Class & Struct
Native Data Type | Managed Data Type |
class | ref class |
struct | value struct |
enum | enum class |
std::string | String^ |
std::map | Dictionary^ |
std::vector | List^ |
std::list | List^ |
function pointer | delegate |
C++/CLI 에서 클래스는 Reference Type (.NET Framework 에서 클래스는 Reference Type 이므로 당연한 소리) 이다. Reference Type 의 인스턴스는 결코 스택에 할당되지 않는다. Reference Type 의 인스턴스는 힙에 할당된다. 그러나 이 힙은 Managed Heap 이라 불리며 Native type 이 사용하는 힙과는 다르다. "new" 키워드는 Native Heap 에 메모리를 할당하며, "gcnew" 는 Managed Heap 에 메모리를 할당한다. gcnew 를 사용하여 선언하는 방법은 다음과 같다.
위 방법은 C++/CLI 에서 Managed 객체를 생성하는 방법이다. Managed Heap 에 생성된 인스턴스에 접근하기 위해서는 "객체 참조 (Object Reference)" 또는 "Handle" 이라 불리는 것(위의 코드에서 objRef)을 통하여 접근 가능한데 이들은 스택에 할당된다. 객체 참조를 통하지 않고서는 인스턴스에 접근할 수 없다. 본질적으로 객체 참조는 주소를 물고 있다. 하지만 Native Code 의 포인터와는 같지 않다. 객체 참조는 포인터와 다르게 포인터 연산을 할 수 없다. Managed Heap 에 인스턴스는 하나 이상의 Reference 를 갖는다. 따라서 다른 객체로 객체 참조 shallow copy 가 가능하다.
.NET Framework 의 CLR 은 매우 영리하며, Garbage Collection 이 있기 때문에 프로그래머가 메모리 해제에 대해서 걱정할 필요가 없다. 하지만 Database open 과 같이 사용자가 할당한 메모리에 대해서는 사용자가 책임지고 메모리 해제 작업을 해주어야 한다. 다음은 C++/CLI 의 클래스 예 이다.
※ ref class
ref class 로 선언하게 되면 Managed Code 가 되어 가비지 컬렉터의 관리를 받게 된다.
ref class 로 선언되지 않은 클래스는 가비지 컬렉터의 관리를 받지 않으며 Unmanaged Code 이다. 따라서 일반 클래스로 동적 메모리 생성을 하였다면 직접 메모리를 해제시켜 주어야 한다.
※ ref class 작성 예
※ Destructor (소멸자)
일반적인 클래스와 마찬가지로 ref class 역시 소멸자가 존재한다. 또한 사용하는 방법 역시 똑같다. 하지만 ref class 의 소멸자는 IDisposable 인터페이스를 구현한 후에 컴파일러가 소멸자의 호출을 Dispose() 호출로 번역한다. 또한 finalizer 호출이 있는데 이는 Gabage Collector 에 의해 호출되며 "!MyClass()" 와 같이 정의된다. finalizer 는 소멸자가 호출되었는지 확인한 다음에 호출되지 않았다면 소멸자를 호출시켜준다.
■ Declaring and Consuming a Managed Class
1. 전형적인 방법
위 코드에서 caret [^] 는 변수 sysDir 이 Reference 인스턴스를 가리키고 있는 객체 참조 임을 나타낸다. 객체 참조를 통하여 클래스의 public 메소드를 호출할 수 있고, 또다른 객체 참조로 복사할 수 있다. ^ 으로 선언한 객체 참조는 gcnew 키워드를 통하여 Managed Heap 에 메모리 할당 되며 이 메모리는 Garbage Collector 의 관리를 받는다.
2. shallow copy
Managed Heap 에 생성된 Reference 참조를 sysDir 객체 참조가 가리키고 있는데, sysDir2 역시 같은 곳을 가리키게 하는 방법이다.
3. Invoke method
객체 참조 sysDir 을 이용하여 public 메소드를 호출(Invoke) 하는 방법이다.
4. 객체 참조의 매개변수로의 전달
메소드의 매개변수로 객체 참조가 전달 되었다. 이 메소드 안에서 똑같은 객체에 대해서 작업할 수 있다. 객체 참조가 전달 될 때 복사 생성자는 호출되지 않는다. 즉, 객체의 복사본은 생성되지 않는다. 이것은 C++ 의 포인터를 넘겨 주는 방법과 비슷하다. 만약 복사본을 생성해야 한다면 당신이 작성한 클래스는 System::IClonalbe 인터페이스를 상속 받아야 하고, Clone() 메소드를 구현해야 한다.
5. 객체 참조의 리턴
위의 코드결과 Directory 객체가 생성된다. 할당된 인스턴스를 가리키고 있는 객체 참조가 리턴된다. 리턴된 후에 dirObj 는 Managed Heap 에 있는 객체를 더이상 가리키지 않는다. 리턴되는 객체 참조를 할당 받고, 그것을 보존하는 것은 메소드를 호출하는 쪽의 책임이다.
■ Abstract Class
클래스에 abstract 키워드를 붙이면 Managed Class 를 추상 클래스로 만든다. 이 방법은 추상 메소드(순수 가상 메소드) 선언 없이 클래스를 추상화 시키는 편리한 방법이다. 또한 메소드는 abstract 키워드로 선언된다.
■ 생성자
C++/CLI 클래스의 생성자는 기본 인수(Default parameter)를 가질 수 없다.
namespace ManagedMemFileEx { public ref class CCliMemFileEx { public: explicit CCliMemFileEx(System::UInt32 _nGrowBytes = 1024); virtual ~CCliMemFileEx(); }; }
위와 같이 기본 인자를 가진 생성자를 정의하면 다음과 같은 에러 메시지를 출력 한다.
"오류 1 error C3222: '_nGrowBytes' : 제네릭 함수 또는 관리되는 형식의 멤버 함수에 대한 기본 인수를 선언할 수 없습니다."
■ 참조
1. C++/CLI Primer - Enter the World of .NET Power Programming (CodeProject)
2. Quick C++/CLI - Learn C++/CLI in less than 10 minutes (CodeProject)
출처 : http://six605.tistory.com/385
반응형
'Programming > C++/CLI' 카테고리의 다른 글
C++ Interop 사용(암시적 PInvoke) (0) | 2010.09.14 |
---|---|
C++/CLI에 대해서 알아두어야 할 것들 (0) | 2010.09.13 |
Win32 API TYPE <-> C# TYPE (0) | 2010.07.20 |
C#, Managed C++ 참고 자료 (0) | 2010.06.25 |
C++/CLI 빌드 시, LNK2019 에러 #3 (0) | 2010.06.07 |