블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2794)
Unity3D (852)
Programming (478)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (185)
협업 (11)
3DS Max (3)
Game (12)
Utility (68)
Etc (98)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (55)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday

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

반응형
Posted by blueasa
, |