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

카테고리

분류 전체보기 (2328)N
Unity3D (572)N
Programming (472)
Unreal (4)
Gamebryo (56)
Tip & Tech (185)
협업 (34)
3DS Max (3)
Game (12)
Utility (116)
Etc (92)
Link (31)
Portfolio (19)
Subject (90)
iOS,OSX (38)
Android (13)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (1)
Memories (19)
Interest (37)
Thinking (36)
한글 (26)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (19)
Exercise (3)
나만의 맛집 (2)
냥이 (9)
육아 (9)
Total1,346,224
Today30
Yesterday132
Statistics Graph

달력

« » 2019.12
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        

공지사항

태그목록

gcnew로 생성하지 않기

 

C++/CLI는 클래스를 생성할 때 ‘gcnew’를 사용하지 않고 생성할 수도 있습니다.

 

리스트 1. ‘gcnew’를 사용하지 않고 클래스 생성하기 >

#include "stdafx.h"

#include <stdio.h>

 

using namespace System;

 

ref class ManagedTest

{

public:

           ManagedTest() { Console::WriteLine(L"New ManagedTest"); }

           ~ManagedTest() { Console::WriteLine(L"delete ManagedTest"); }

          

           void func() { Console::WriteLine(L"Call func() - {0}", nNumber ); }

 

           int nNumber;

};

 

void foo1()

{

           ManagedTest MTest;

           MTest.nNumber = 1;

           MTest.func();

}

 

void foo2()

{

           ManagedTest^ MTest = gcnew ManagedTest();

           MTest->nNumber = 2;

           MTest->func();

}

 

int main(array<System::String ^> ^args)

{

           foo1();

           foo2();

          

           getchar();

           return 0;

}


결과 >


<리스트 1> ManagedTest MTest; 는 비 관리 C++처럼 GC가 아닌 스택 영역에 생성하는 것으로 착각할 수도 있겠지만 전혀 아닙니다클래스를 생성하면 언제나 GC 영역에 만들어집니다

위의 코드는 그냥 ‘gcnew’ 사용을 우리가 생략하고 컴파일러가 대신 써 준다고 생각하시면 됩니다.

 

void foo1()

{

           ManagedTest MTest;

           MTest.nNumber = 1;

           MTest.func();

}

은 컴파일러에 의해서 아래의 코드로 바뀝니다.

void foo1()

{

           ManagedTest^ MTest = gcnew ManagedTest();

           MTest->nNumber = 1;

           MTest->func();

           delete MTest;

}

 

위의 코드를 보시면 아시듯이 gcnew를 사용하지 않고 클래스를 생성하면 우리가 직접 delete를 쓰지 않아도 되는 편리함을 얻을 수 있습니다.

gcnew를 사용하지 않는 것은 C#에서 ‘using’을 간략화 시킨 것으로 생각하면 좋습니다.


< C# using 문 사용 예 >

using (Graphics g = this.CreateGraphics())

{

    g.DrawLine(Pens.Black, new Point(0,0), new Point(3,5));

}

 

 

 

 

value 클래스

 

관리 클래스는 복사 생성자와 대입 연사자를 가지지 못하므로 아래의 코드는 컴파일 에러가 발생합니다.

 

리스트 2. >

#include "stdafx.h"

#include <stdio.h>

 

using namespace System;

 

ref class C {

    int i;

};


void func(C c) {}


int main()

{

    C c;

    C d;

    func(c);   // 에러

    d = c;     // 에러

}

 

그러나 클래스를  ‘ref’가 아닌 ‘value’ 클래스로 정의하면 위의 코드는 컴파일 할 수 있습니다.

 

#include "stdafx.h"

#include <stdio.h>

 

using namespace System;

 

value class C {

    int i;

};

void func(C c) {}

int main()

{

    C c;

    C d;

    func(c);   // 에러

    d = c;     // 에러

}

 

value 클래스는 클래스간 복사를 할 수 있는 능력이 있습니다이 복사는 비트 단위의 복사로 이른바 ‘memcpy’와 같은 복사입니다.

value 클래스는 복사를 할 수 있으므로 value 클래스의 멤버는 절대 복사 가능한 멤버만 가질 수 있습니다그래서 아래와 같은 value 클래스 C는 컴파일 에러가 발생합니다.

 

ref class A

{

  int i;

};

 

value class C

{

  A a;

};

 

 

 value 클래스의 특징으로는 ref 클래스가 GC에서 만들어지는 것과 달리 스택에 만들 수 있습니다.

value class C

{

};

 

C c;

 

위 코드에서 클래스는 스택에 만들어집니다(물론 gcnew를 사용하면 GC에 만들어집니다)

 

value 클래스의 특징은 좀 더 있는데 위에 설명한 것들과 포함해서 아래와 같이 정리할 수 있습니다.

 


value 클래스의 특징

 

1. 기본 생성자를 가질 수 없다.

2. 복사 생성자를 가질 수 없다.

3. 대입 연산자를 가질 수 없다.

4. 소멸자를 가질 수 없다.

5. finalize를 가질 수 없다.

6. 클래스간 복사를 할 수 있다.

7. 복사 불가능한 것을 멤버로 가질 수 없다(ref 클래스 등).

8. 스택에 생성할 수 있다.

9. 다른 클래스를 계승할 수 없다( interface는 가능하다)

 

 

 


관리 클래스를 파라메터로 넘기기

 

ref class A

{

           int i;

};

 

void foo1( A a )

{

}

 

함수 foo1의 파라미터 정의는 클래스 A value 클래스일 때만 사용할 수 있습니다그러므로 아래와 같이 foo1의 파라미터를 정의해야 합니다.

void foo1( A^ a )

{

}

 

 

 

 

그 외….

 

C++/CLI에서 참조는 ‘%’을 사용합니다이것은 비 관리의 ‘&’와 구별이 됩니다.

%는 아래와 같은 경우에 유용하게 사용할 수 있습니다.

void foo( A^ a )

{

}

 

A a;

// foo( a );  // 에러

foo( %a ); // 성공


참조는 C#에서는 'ref', VB.NET에서는 'ByRef'와 같다고 생각하시면 됩니다.


// 값을 참조로 넘기는 경우

void valuebyref(int%i)
{
   i=5;
}

// 참조형을 참조로 넘기기
void refbyref(String^%s)
{
   s="newstring";
}

void main()
{
   int i=1;

   valuebyref(i);

   String^s="basestring";
   refbyref(s);
}
( 위 코드는 http://adversaria-june.blogspot.com/2006/08/ccli_26.html 에서 인용했습니다 )

 



구조체는 관리나 비 관리나 다른 점은 없습니다.


 

참조와 구조체는 너무 짧게 끝나버렸네요^^;


출처 : http://vsts2010.net/323

http://vsts2010.net/323

Posted by blueasa

댓글을 달아 주세요