[ VC11 ] 대격변(?) Visual C++ 11

Visual C++ 10 2012. 6. 25. 09:00 Posted by 알 수 없는 사용자

드디어 Visual Studio 2012(이하 VS2012) RC판이 나왔습니다(사실 꽤 되었죠^^;). 

이번 VS Visual C++(이하 VC++)의 버전은 11이 됩니다.

 

한동안 Visual C++은 변화가 거의 없다가 VC++ 9(VS 2008)에서 변화의 조짐을 보이다가 VS 2010에서 새로운 C++ 표준인 C++11(그 당시에는 C++0x라고 부름)과 병렬 프로그래밍, 툴의 기능 강화를 통해서 이전에 비해서 큰 변화를 이루었습니다.

또 이번 VS 2012에서도 VS 2010 버전 이상으로 큰 변화가 생겼습니다. 변화는 대격변이라고 부를 수 있을 정도입니다!.

 

 

이번에는 다음과 같은 변화가 있습니다.

 

1. Windows 8 Metro 앱 개발

아주 큰 변화 중의 하나입니다. 정식 제품이 가을쯤에 나올 Windows 8 Metro Windows Phone 8용 앱을 C++을 사용하여 개발할 수 있습니다. 이것을 위해 WinRT라는 새로운 플랫폼 API C++/CX가 새로 생겼습니다.

 

2. 툴 기능

다양한 C++ 토큰들에 다양한 색을 지정.

찾을 요소를 눈에 잘 뛰게 해준다.

편의 기능이 코딩 시 멤버 선택.

인텔리센스에서 C++/CLI 지원.

코드스니펫을 이용한 고속 코딩.

 

3. C++11 지원

이번에는 코어 언어 기능 보다는 라이브러리 기능이 더 중심이 되었습니다. 그러나 코어 언어에서 VC++ 10에서 큰 사랑을 받은 auto에 버금가는 range-based for loop가 있습니다. 그리고 라이브러리에 Thread가 추가 되었습니다. 이번에는 공부할 것이 많습니다 ^^;

 

4. 컴파일러 개선

CPU 개수에 맞추어 컴파일 속도가 향상.

Auto-Vectorizer 의한 프로그램 성능 향상.

 

5. 병렬 프로그래밍

기존의 병렬 라이브러리 개선.

새로운 디버깅 및 시각화 기능에 의해 쉽고 올바른 병렬 프로그래밍 진단.

GPU 병렬 프로그래밍을 위한 C++ AMP 추가.

 

6. 네이티브 유닛테스트 프레임웍 추가

사제가 아닌 마이크로소프트 순정의 유닛테스트 프레임웍!!!.

 

 

 

이렇게 VC++ 11의 새로운 기능을 정리해 보았습니다. 제가 대충 큰 것만 정리했는데도 공부할 것이 많지 않습니까?^^; 한번에 다 하면 부담되지만 조금씩 하면 충분히 공부할만한 분량입니다. 아직 정식 버전이 나오지 않았으니(가을쯤에 나온다고 합니다) 여유를 가지고 지금부터 조금씩 천천히 공부해 보죠^^

 

 

 

 

 

ps 1: VC++의 각 버전 별 내부 버전 번호와 코드에 정의된 버전

브랜드 버전                  내부 버전          #define _MSC_VER 버전

Visual C++ 2005            VC8                 1400

Visual C++ 2008            VC9                 1500

Visual C++ 2010            VC10                1600

Visual C++ 2012            VC11                1700

 

 

ps 2: 실행 환경

위에는 VC++11의 좋은 점만 이야기 했지만 개인적으로 걱정되는 것이 있습니다. 가장 큰 문제가 실행 환경입니다. VC++11Windows Vista 이상에서만 실행되고 또 VC++11을 이용해서 만든 프로그램도  Windows Vista  이상에서만 실행할 수 있습니다.

Windows 8 Metro 앱 개발을 하거나 저처럼 서버 개발을 하는 개발자에게는 큰 문제가 되지 않을 수도 있지만 클라이언트 개발자에게는 이 부분이 VC++11을 사용하는데 큰 걸림돌이 되리라 생각합니다

 => 그런데 VC++ 팀블로그를 보니 많은 고객들이 XP 지원을 요청해서 가을쯤에 업데이트를 통해서 XP도 지원해 준다고 합니다.^^ 

http://blogs.msdn.com/b/vcblog/archive/2012/06/15/10320645.aspx

이로써 큰 고민을 하나 해결 되었네요^^

 

[미리 보는 C++11] 8. Placement Insert

C++0x 2012. 2. 27. 09:00 Posted by 알 수 없는 사용자

Placement Insert C++11의 기능 중에 하나로 STL 컨테이너와 관계가 있습니다.

 

struct ITEM

{

ITEM( int nCode )

{

}

};

 

std::vector< ITEM > Items;

Items.push_back( ITEM( 1 ) );

 

현재까지는 위 코드처럼 ITEM이라는 객체를 Items 컨테이너에 생성과 동시에 추가를 할 때는 위와 같이해야 합니다. 그런데 위 방식으로 하면 추가를 위해 컨테이너에 한번 생성을 한 후 복사를 해야 하는 문제가 발생합니다(또 임시 객체 만들므로 삭제 비용도 발생합니다).

이와 같은 동작은 우리가 원하는 것이 아닙니다.

그래서 C++11에서는 이와 같은 문제를 해결했습니다. 바로 Placement Insert가 해결했습니다.

 

C++11‘Placement Insert’를 사용하면 위의 코드는 아래와 같이 할 수 있습니다.

std::vector< ITEM > Items;

Items.emplace_back( 1 );

 

emplace_back push_back과 같지만 Placement Insert 기능이 구현된 것으로 임시 오브젝트를 만들면서 발생하는 비용을 없애줍니다.

 

C++11의 각 컨테이너에는 Placement Insert와 관련된 멤버로
emplace(insert),
emplace_back(push_back),
emplace_front(push_front),
emplace_hint(insert.
연관 컨테이너 용)
가 추가됩니다.

 

Placement InsertC++11의 새로운 기능인 가변 인수 템플릿을 사용하여 구현되었습니다.

 

 

Placement Insert는 아래와 같은 주의할 점도 있습니다.

1. explicit 문제.

   explicit 생성자도 암묵적으로 호출됩니다.


2. "0" 문제.

생성자의 파라미터가 포인터인 경우 인자로 0을 넘기면 int로 추론합니다. 그래서 이 경우에는 nullptr을 사용해야 합니다.

 

[미리 보는 C++11] 4. constexpr - 2

C++0x 2011. 9. 23. 09:30 Posted by 알 수 없는 사용자

constexpr를 클래스에 사용


constexpr을 클래스에서 사용하면 클래스를 정수로 사용할 수도 있으며 메타 템플릿 프로그래밍에서는 이전에는 복잡하게 처리하던 것을 아주 간단하게 처리할 수도 있습니다. C++ 메타 템플릿 프로그래밍에 관심이 많구나 자주 사용하고 있는 분들에게는 constexpr 덕분에 프로그래밍이 한결 편해지리라 생각합니다.

 

아래의 코드는 Integer 이라는 클래스를 constexpr을 사용하여 정수처럼 사용 합니다.

class Integer

{

private :

    int value ;

 

public :

    constexpr Integer() : value() { }

    constexpr Integer( int value ) : value(value) { }

 

    constexpr operator int() { return value ; }

} ;

 

int main()

{

    constexpr Integer size = 5 ; // 컴파일 타임에 정수로

 

    int x[size] ; // Integer::operator int()가 호출된다

 

    Integer object ; // 일반적인 클래스 인스턴스 화. 실행 시에 처리

    int y[object] ; // 당근 에러

}

출처 : http://cpplover.blogspot.com/2010/11/gccniconstexpr.html

 


또 메타 템플릿 프로그래밍에서는 아래와 같이 사용할 수도 있습니다.

#include <iostream>

 

struct pi {

    static constexpr double value = 3.14;

};

 

template <const double& r>

struct circle_area {

    static constexpr double value = r * r * pi::value;

};

 

struct radius {

    static constexpr double value = 2.5;

};

 

int main()

{

    constexpr double result = circle_area<radius::value>::value;

 

    static_assert(result == 19.625, "not equal");

    std::cout << result << std::endl;

}

출처 : http://d.hatena.ne.jp/faith_and_brave/searchdiary?word=constexpr&.submit=%B8%A1%BA%F7&type=detail

 

 

constexpr은 컴파일 할 때 결과가 이미 결정 나는 것은 컴파일 타임 때 처리를 해주어 실행 시에 불필요한 처리를 막아주고, 기존의 메타 템플릿 프로그래밍으로 까다롭게 만들었던 것을 아주 쉽게 구현할 수 있게 해줍니다.

 

C++11에서는 constexpr을 잘 사용하면 기존 보다 더 뛰어난 프로그래밍을 할 수 있으니 깊게 파고들 가치가 있다고 생각합니다.

[미리 보는 C++11] 3. constexpr - 1

C++0x 2011. 9. 15. 09:00 Posted by 알 수 없는 사용자

constexpr는 변수, 함수, 클래스를 컴파일 타임에 정수로 사용할 수 있도록 해줍니다. 즉 상수로 취급할 수 있는 작업은 컴파일 타임에 처리하도록 할 수 있습니다.

 

constexpr를 변수에 사용

constexpr int aa = 11;

이것은

const int aa = 11

와 같은 의미를 가집니다.

 

그러나 아래와 같이는 사용할 수 없습니다.

int input_num = 0;

constexpr int aa = input_num;  // 에러


constexpr
로 지정된 변수는 꼭 컴파일 시에 정수가 되기 때문에 변수 선언 시 대입이 정수 식이어야만 합니다. const와의 차이는 const는 컴파일 시에 정수가 아니어도 괜찮고 변수 선언 시 대입 값이 정수 식인 경우 정수 식이 되고, 그렇지 않은 경우는 단순히 const를 수식하는 것이 됩니다(이에 비해 constexpr는 꼭 정수 식이어야만 합니다).

 

 

 

constexpr를 함수에 사용

C++03에서는 아래의 코드는 에러가 됩니다.

int GetNum() { retun 5; }

int Numbers[ GetNum() ];

GetNum 함수는 상수 5를 반환 하는 것으로 이미 컴파일 시에 반환 값을 알 수 있습니다. 그러나 컴파일러는 GetNum 이라는 함수가 정수처럼 사용할 수 있는지 알 수 없으므로 정수로 취급하지 않습니다.

 

위 코드는 C++11constexpr를 사용하면 우리가 원하는 대로 GetNum 함수를 정수로 사용할 수 있습니다.

 

constexpr int GetNum() { retun 5; }

int Numbers[ GetNum() ];

 

constexpr를 함수에 사용할 때는 꼭 함수 본체는 { return expression; } 형태가 되어야만 합니다.

 

 

constexpr 변수는 비 constexpr 변수에 사용할 수 있으므로 아래와 같은 테크닉도 사용할 수 있다.

constexpr double power( double x, unsigned int y )

{

    return y == 1 ? x : x * power( x, y - 1 ) ;

}

 

int main()

{

    // 정수 식

    constexpr double a = power( 2, 32 ) ;

 

    // 정수 식이 아니다

    double x = 2 ; unsigned int y = 32 ;

    double b = power( x, y ) ;

}

(출처) http://cpplover.blogspot.com/2010/11/gccniconstexpr.html

 

 

그리고

const int base_HP = 200;

int NPC_Lv1_HP = base_HP + 0;

int NPC_Lv2_HP = base_HP + 200;

라는 코드는 정수 계산을 하는데 실행 시에 계산되는데 이것을 constexpr을 사용하여 컴파일 시에 계산되게 할 수 있습니다.

 

constexpr int AssignHP( int nPlusHP )

{

 return base_HP + nPlusHP;

}

 

int NPC_Lv1_HP = AssignHP( 0 );

int NPC_Lv2_HP = AssignHP( 200 );



 

[미리 보는 C++11] 2. override와 final

C++0x 2011. 8. 30. 00:18 Posted by 알 수 없는 사용자

현재의 표준 C++에서는 부모 클래스의 특정 멤버를 오버라이드 할 때 virtual을 앞에 붙입니다.

struct Base

{

  virtual void foo( int i );

};

 

struct Derived : Base

{

  virtual void foo( int i );

}

 위의 예제와 같은 작은 코드를 만질 때는 실수를 하지 않지만 실제 일을 할 때는 크고 많은 클래스를 다루다 보면 실수를 할 수 있습니다. 위 예제의 경우 아래와 같은 실수를 할 수 있습니다.

struct Derived : Base

{

  virtual void foo( float i );

}

위와 같이 실수를 하면 Derived의 foo 멤버함수는 Base foo 멤버함수를 오버라이드 하지 않게 됩니다. 이런 실수는 에러가 아니기 때문에 골치 아픈 삽질을 할 수도 있습니다.

이런 문제를 방지하기 위해서 override가 새로 생겼습니다.

struct Derived : Base

{

  virtual void foo( float i ) override;

}

이렇게 override를 사용하게 되면 컴파일 할 때 Base 클래스에

void foo( float i )가 없는데 오버라이드 한다고 에러를 발생시켜 줍니다.

 

 

때로는 Base 클래스의 특정 멤버함수를 Derived 클래스에서 오버라이드 하지 못하도록 막고 싶은 경우가 있을 것입니다. 이때는 final을 사용합니다.

struct Base

{

  virtual void foo( int i ) final;

};

 

struct Derived : Base

{

  virtual void foo( int i );

}

위의 코드에서는 Base 클래스의 foo 멤버함수를 final로 오버라이드 못하도록 해 놓았기 때문에 컴파일을 하면 에러가 발생합니다.

 

 

 

참고

위키피디아 http://en.wikipedia.org/wiki/C%2B%2B0x

 

C++0x가 드디어 C++11이 되었습니다.

C++0x 2011. 8. 15. 16:02 Posted by 알 수 없는 사용자

새로운 C++ 표준 작업이 언제쯤에나 끝날지 고대하고 있는 분들에게 반가운 소식이 있습니다.

드디어 C++0x 작업이 거의 마무리 되었습니다.

 

저번 주 수요일에 최종 국제 투표가 끝난 후 드디어 결과가 나왔는데 만장 일치로 승인이 되었습니다. 이제는 앞으로 몇 달 후에 ISO로부터 최종 발행만 기다리면 됩니다(즉 서류적인 절차만 남았습니다).

 

이로써 길게 길게 진행된 C++의 새로운 표준 작업은 끝나게 되어서 이제 C++11로 불리게 되었습니다( 이전에는 C++98, C++03이 있었습니다 ).

 

C++은 특정 회사가 주도하지 않고, 기존에 C++로 만들었던 코드가 문제 없이 동작해야 하고(표준 사양만 지켰다면), 성능과 편리성을 모두 가지려고 하니 많은 시간이 걸렸습니다.

 

아직 ISO에서 최종 문서가 나오지 않았고 무료로 최종 사양이 어떻게 되었는지 궁금한 분들은 http://t.co/5mjCzyJ 를 통해서 문서를 받아보기 바랍니다. 이 문서는 워킹 드래프트 3242 ISO에서 나올 사양 문서와 거의 같을 것입니다(참고로 ISO에서 나온 문서는 유료입니다).

 

이제 우리는 앞으로 나올 Visual C++이 과연 얼만큼 새로운 표준 기능을 구현해 줄지가 기대됩니다. 개인적으로 꽤 많은 부분이 구현되리라 생각하고 혹 빠진 부분은 예전의 tr1처럼 서비스 팩에서 구현되지 않을까 생각합니다.

 

C++ 새로운 표준이 정해졌으니 남보다 앞서기를 바라는 C++ 프로그래머들은 새로운 C++ 표준을 공부해 봅시다. ^^

 

근래에 바빠서 글을 거의 올리지 못했는데 다음 글은 새로운 C++ 표준의 바뀐 부분을 간단하게 설명하는 글을 올릴 예정입니다.

그리고 새로 추가되는 표준 라이브러리는 boost 라이브러리에서 많이 들어왔습니다. 그래서 지금이라도 boost 라이브러리를 다운로드 받으면 새로운 표준에 들어갈 라이브러리를 미리 사용할 수 있습니다.

 

 


참고

C++0x 사양

위키피디아

http://en.wikipedia.org/wiki/C%2B%2B0x

GCC feature 테이블

http://gcc.gnu.org/projects/cxx0x.html

 

boost 라이브러리

설치 버전 다운로드

http://www.boostpro.com/download/

공식 홈페이지

http://www.boost.org

 

 

 

MSDN을 보다 보니 C++/CLI의 델리게이트에 네이티브용 함수를 할당할 수 있는 방법이 있어서 소개합니다. 아래의 코드는 MSDN에 있는 것입니다.

 

#pragma unmanaged

extern "C" void printf(const char*, ...);

class A {

public:

   static void func(char* s) {

      printf(s);

   }

};

 

#pragma managed

public delegate void func(char*);

 

ref class B {

   A* ap;

 

public:

   B(A* ap):ap(ap) {}

   void func(char* s) {

      ap->func(s);

   }

};

 

int main() {

   A* a = new A;

   B^ b = gcnew B(a);

   func^ f = gcnew func(b, &B::func);

   f("hello");

   delete a;

}

< http://msdn.microsoft.com/ja-jp/library/9cy3ccxx%28v=VS.80%29.aspx >

 

위 코드 중 #pragma unmanaged 지시어 이하는 컴파일러에서 비관리코드로 취급합니다. 그리고 #pragma managed 이하는 관리코드로 취급합니다. 내용이 간단하고 어려운 부분이 없기 때문에 따로 자세한 설명은 생략하겠습니다.

 


C++/CLI는 단순하게 닷넷 플랫폼에서 사용할 수 있는 C++ 언어라기 보다는 C++ 언어의 부족한 부분을 진화 시킨 언어라고도 생각할 수 있는 부분이 꽤 있습니다. 그러나 C++/CLI는 C++과 C#의 중간의 애매한 위치에 있어서 양쪽 프로그래머 모두에게 별로 호응을 받지 못하는 것 같습니다. 그래서 C++/CLI 관련 글을 제가 처음에 생각했던 것보다는 조금 일찍 끝낼려고 합니다.

C++/CLI를 사용하는 대부분의 프로그래머들은 아마 기존의 비관리 코드를 관리코드에서 사용하고 싶을 때라고 생각합니다. C++/CLI의 기능 소개는 이번으로 일단 끝내고 앞으로는 비관리코드와의 연계에 대해서 실제 사례 보여주면서 설명하려고 합니다.


사례는 오픈 소스 네트워크 라이브러리인 HalfNetworkC++/CLI를 사용하여 관리코드에서 사용할 수 있도록 wrapping한 후 이것을 관리코드에서 사용할 예정입니다.

HalfNetwork는 온라인 게임 서버 프로그래머인 임영기님이 만든 것으로 ACE 라는 오픈 소스 네트워크 라이브러리를 사용하기 편하게 만든 라이브러리입니다.

 

소스 위치 http://code.google.com/p/halfnetwork/

문서 http://code.google.com/p/halfnetwork/w/list http://jacking.tistory.com/category/HalfNetwork

임영기님 블로그 http://javawork.egloos.com/

 

요즘 공부할 것은 너무 많은데 따라갈 시간은 부족해서 다음 글은 언제쯤 올리지 정확하게 알 수 없지만 최대한 빨리 다음 글들을 올려서 C++/CLI을 2010년 안에는 끝내고 내년에는 새로운 주제로 시작하겠습니다^^

 

119일에 오후 2시에 양재역 엘타워에서 한국 마이크로소프트와 인텔이 주최하고 월간 마이크로소프트웨어에서 주관한 ‘C++ & 게임 개발자를 위한 개발 생산성 및 퍼포먼스 향상 전략 세미나가 열렸습니다.

http://new.imaso.co.kr/seminars/game

 

아직 가을이지만 겨울이라는 생각이 들 정도로 추운 날씨였지만 많은 개발자 분들이 참석하셨습니다. 저는 요즘 회사가 바쁜 관계로 오전까지 일하다가 가서 좀 늦었더니 세미나 장은 이미 만원이더군요.

 


이 날 세미나에서 팀블로그에서 DX11을 연재하고 계신 박민근님과 제가 강연자로 참여했습니다. 박민근님은 예제로 느껴보는 DX11의 매력이라는 세션을 통해서 실제 DX11의 새로운 기능이 어떻게 사용되는지 보여주셨습니다. 원래 이날 실제 코드를 컴파일 해서 실행되는 모습을 보여 줄 예정이었지만 DX11을 지원하는 노트북을 구하지 못해서 안타깝게 집에서 찍은 영상으로 대체해서 보여주었습니다. 아마 다음에 DX11 관련 세미나가 있을 때는 컴파일 해서 돌아가는 모습을 볼 수 있을 테니 기다려주세요^^

제 시간에 가지 못해서 뒤에서 사진을 찍으니 박민근님이 작게 나오는군요^^;


15분인가 20분 정도 남을 때부터 5분 간격으로 남은 시간을 알려주더군요


저는 ‘C++ 프로그래머가 알아야 할 병렬 프로그래밍 상식이라는 주제로 병렬 프로그래밍과 관련된 하드웨어, 플랫폼, 아키텍처 그리고 용어나 Tip을 정리한 세션이었습니다. 강연 중 중앙의 스크린이 잠시 나가기도 하고고 10분을 남겨진 시점에서 노트북 밧데리가 얼마 남지 않았다는 경고 창이 발생하는 돌발 상황이 발생했지만 무사히 강연을 마쳤습니다.




박민근님과 저 이외에 인텔에서 두 분이 인텔의 병렬프로그래밍 관련 툴이나 라이브러리를 소개하셨습니다.


행사장에서는 Visual Studio 책자를 나누어 주고 있었고, 세미나가 끝난 후에는 제가 적은 C++0x 책도 배포되었습니다.^^


[Step. 16] array 클래스에 non-CLI 오브젝트 사용

C++/CLI 2010. 10. 27. 09:00 Posted by 알 수 없는 사용자

C++/CLI은 네이티브 C++과 다르게 자료구조 배열을 사용하기 위해서는 array 컨테이너를 사용합니다.

array 컨테이너는 기본적으로 non-CLI 오브젝트는 사용할 수가 없습니다. 그러나 non-CLI 오브젝트가 포인터라면 사용할 수 있습니다.

 

아래는 array 컨테이너에 non-CLI 오브젝트를 사용한 경우입니다.

using namespace System;

 

class CNative

{

public:

           CNative()

           {

                     Console::WriteLine(__FUNCTION__);

           }

           ~CNative()

           {

                     Console::WriteLine(__FUNCTION__);

           }

};

 

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

{

           array<CNative>^ arr = gcnew array<CNative>(2);

           return 0;

}

 빌드하면 위에 이야기 했듯이 아래와 같은 빌드 에러가 발생합니다.


 

그럼 이번에는 non-CLI 오브젝트의 포인터를 사용해 보겠습니다.

#include "stdafx.h"

#include <iostream>

using namespace System;

 

class CNative

{

public:

           CNative()

           {

                     Console::WriteLine(__FUNCTION__);

           }

           ~CNative()

           {

                     Console::WriteLine(__FUNCTION__);

           }

};

 

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

{

           array<CNative*>^ arr = gcnew array<CNative*>(2);

           for(int i=0; i<arr->Length; i++)

           {

                     arr[i] = new CNative();

           }

 

           getchar();

           return 0;

}


이번에는 빌드에 문제가 없어서 아래와 같이 실행결과가 나옵니다.


 

그러나 위의 실행 결과를 보면 이상한 점을 발견하실 수 있을 것입니다. 그것은 CNative 오브젝트의 생성자는 호출하지만 파괴자는 호출되지 않은 것입니다. 이것은 array 컨테이너는 CLI 객체이므로 GC에서 관리하지만 non-CLI 오브젝트를 포인터 타입으로 사용한 것은 GC에서 관리하지 않으므로 만약 array GC에서 소멸 되기 전에 array에 담겨있는 non-CLI 오브젝트를 메모리(new로 할당한)를 해제하지 않으면 메모리 해제가 되지 않아서 메모리 릭이 발생합니다.

 

그래서 아래와 같이 array GC에서 소멸되기 전에 메모리를 해제하도록 해야합니다.

#include "stdafx.h"

#include <iostream>

using namespace System;

 

class CNative

{

public:

           CNative()

           {

                     Console::WriteLine(__FUNCTION__);

           }

           ~CNative()

           {

                     Console::WriteLine(__FUNCTION__);

           }

};

 

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

{

           array<CNative*>^ arr = gcnew array<CNative*>(2);

           for(int i=0; i<arr->Length; i++)

           {

                     arr[i] = new CNative();

           }

 

           for(int i=0; i<arr->Length; i++)

           {

                     delete arr[i];

           }

          

           getchar();

           return 0;

}

 

실행 결과


이번에는 CNative의 파괴자가 제대로 호출되고 있습니다.



출처

도서 "C++/CLI In Action"

C++/CLI를 공부하시는 분들은 "C++/CLI In Action" 책을 꼭 한번 보시기를 추천합니다.

[Step. 14] 인터페이스 ( interface )

C++/CLI 2010. 10. 1. 09:30 Posted by 알 수 없는 사용자

인터페이스는 비관리코드에서는 순수가상함수만을 가진 클래스와 같습니다. ‘interface class’라는 키워드를 사용하여 정의하면 이 클래스에는 아래와 같은 형만 멤버로 가질 수 있습니다.

 

함수

프로퍼티

이벤트

 

또한 선언만 가능하지 정의는 할 수 없습니다.

 


C++/CLI ref class C#이나 Java와 같이 다중 상속은 할 수 없지만 인터페이스를 사용하면 다중 상속(즉 인터페이스를 상속)을 할 수 있습니다.

 

interface class IA {

public:

    void funcIA();

};

interface class IB {

public:

    void funcIB();

};

interface class IC {

public:

    void funcIC();

};

ref class A {

    int i;

};

ref class B : A, IA, IB, IC {

public:

    virtual void funcIA() {   }

    virtual void funcIB() {   }

    virtual void funcIC() {   }

};

int main() {

    B^ b = gcnew B;

 

    IA^ ia = b;

    IB^ ib = b;

    IC^ ic = b;

    b->funcIA();

    ia->funcIA();

    ib->funcIB();

    ic->funcIC();

    return 0;

}

 



출처

http://cppcli.shacknet.nu/cli:interface

 

 

[Step. 15] static 생성자, initonly, literal

C++/CLI 2010. 9. 24. 09:00 Posted by 알 수 없는 사용자

static 생성자

 

static 생성자는 클래스의 생성자에서 static 멤버를 초기화 하고 싶을 때 사용합니다.

ref class, value class, interface에서 사용할 수 있습니다.

 

#include "stdafx.h"

#include <iostream>

 

using namespace System;

 

ref class A {

public:

    static int a_;

    static A()

    {

        a_ += 10;

    }

};

ref class B {

public:

    static int b_;

    static B()

    {

//        a_ += 10; // error

        b_ += 10;

    }

};

ref class C {

public:

    static int c_ = 100;

    static C()

    {

        c_ = 10;

    }

};

 

int main()

{

    Console::WriteLine(A::a_);

    A::A();

    Console::WriteLine(A::a_);

 

    Console::WriteLine(B::b_);

 
    Console::WriteLine(C::c_);


     getchar();

    return 0;

}

 

< 결과 >


 

static 생성자는 런타임에서 호출하기 때문에 클래스 A의 멤버 a_는 이미 10으로 설정되어 있습니다. 그리고 이미 런타임에서 호출하였기 때문에 명시적으로 A::A()를 호출해도 실제로는 호출되지 않습니다.

 

클래스 B의 경우 static 생성자에서 비 static 멤버를 호출하면 에러가 발생합니다.

 

클래스 C의 경우 static 멤버 c_를 선언과 동시에 초기화 했지만 런타임에서 static 생성자를 호출하여 값이 10으로 설정되었습니다.

 

 

 

initonly

 

initonly로 선언된 멤버는 생성자에서만 값을 설정할 수 있습니다. 그리고 initonly static로 선언된 멤버는 static 생성자에서만 값을 설정할 수 있습니다.

 

 

ref class C
{
public:
    initonly static int x;
    initonly static int y;
    initonly int z;
    static C()
    {
        x = 1;
        y = 2;
        // z = 3; // Error
    }
    C()
    {
        // A = 2; // Error
        z = 3;
    }
    void sfunc()
    {
        // x = 5; // Error
        // z = 5; // Error
    }
};


int main()
{
    System::Console::WriteLine(C::x);
    System::Console::WriteLine(C::y);
    C c;
    System::Console::WriteLine(c.z);
    return 0;
}

 

 

 

literal

 

literal로 선언된 멤버는 선언과 동시에 값을 설정하고 이후 쓰기는 불가능합니다. 오직 읽기만 가능합니다.

using namespace System;
ref class C
{
public:
    literal String^ S = "Hello";
    literal int I = 100;
};

int main()
{
    Console::WriteLine(C::S);
    Console::WriteLine(C::I);
    return 0;
}



참고
http://cppcli.shacknet.nu/cli:static%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF
http://cppcli.shacknet.nu/cli:initonly
http://cppcli.shacknet.nu/cli:literal





'C++/CLI' 카테고리의 다른 글

[Step. 16] array 클래스에 non-CLI 오브젝트 사용  (0) 2010.10.27
[Step. 14] 인터페이스 ( interface )  (1) 2010.10.01
[Step. 13] parameter array  (1) 2010.09.10
[Step. 12] for each  (1) 2010.09.03
[Step. 11] 열거형( enum )  (2) 2010.08.27

[Step. 13] parameter array

C++/CLI 2010. 9. 10. 09:00 Posted by 알 수 없는 사용자

비관리코드에서 로그 기능을 구현할 때 주로 가변 길이 인수를 사용합니다.

void LOG( char* szText, ... )

{

}

 


위와 같은 가변 길이 인수를 C++/CLI에서는 parameter array라는 것으로 구현합니다.

void LOG( … array<Object^>^ Values )

{

for each( Object^ value in Values )

{

   ….

}

}

 

int main()

{

LOG( 23 );

LOG( 2, 1, “error” );

 

return 0;

}

 


parameter array를 사용하면 이전 보다 안전하고, 하나의 형이 아닌 다양한 형을 인자로 받아 들일 수 있어서 유연성이 높습니다.

 

그러나 하나의 함수에서 parameter array는 하나 밖에 사용하지 못합니다. 하지만 parameter array가 아닌 형이라면 여러 개 사용할 수 있습니다. 다만 이 때는 parameter array는 가장 마지막 인수가 되어야 합니다.

 

void LOG( int nLogLevel, … array<Object^>^ Values )

{

}

 

 


참고

http://cppcli.shacknet.nu/cli:parameter_array

 

'C++/CLI' 카테고리의 다른 글

[Step. 14] 인터페이스 ( interface )  (1) 2010.10.01
[Step. 15] static 생성자, initonly, literal  (1) 2010.09.24
[Step. 12] for each  (1) 2010.09.03
[Step. 11] 열거형( enum )  (2) 2010.08.27
[Step. 10] 이벤트 ( event )  (0) 2010.08.20

[Step. 12] for each

C++/CLI 2010. 9. 3. 09:00 Posted by 알 수 없는 사용자

데이터셋에 있는 요소를 열거할 때 비관리코드에서는 보통 for문이나 while문을 자주 사용합니다.

그러나 C++/CLI에서는 for each을 사용하여 데이터셋에 있는 요소들을 열거할 수 있습니다.

for each에서 사용할 수 있는 것은 배열 이외에도 아래의 형으로 구현한 것들을 사용할 수 있습니다.

 

1. IEnumerable 인터페이스를 구현한 클래스

2. STL의 이터레이터와 같은 것을 가지고 있는 클래스

 


참고로 VC++ 8(VS 2005)에서는 비관리코드에서도 for each 문을 지원하고 있습니다.

for each를 사용할 때 주의해야 할 점은 열거하는 요소를 변경할 수는 없다는 것입니다.

 

#include "stdafx.h"

#include <iostream>

#include <vector>

#include <map>

 

using namespace std;

using namespace System;

using namespace System::Collections;

 

 

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

{

     // 배열

     array< int >^ Nums = { 0, 1, 2, 3, 4, 5 };

     for each(int value in Nums)

     {

          value = 2;

          Console::WriteLine( value );

     }

    // 위에서 for each 내부에서 요소의 값을 바꾸었지만 아래의 출력 값을 보면

    // 바뀌지 않은 것을 알 수 있습니다.

    for each(int value in Nums)

    {

          Console::WriteLine( value );

    }

 

   

    // 리스트

    ArrayList^ NumList = gcnew ArrayList();

    NumList->Add(1);

    NumList->Add(2);

    NumList->Add(3);

 

    for each(int value in NumList)

    {

        Console::WriteLine(value);

    }

 

 

    // vector

    vector<int> vi;

    vi.push_back(3);

    vi.push_back(4);

   

    for each(int i in vi)

    {

        Console::WriteLine(i);

    }

 

 

    // map

    map<const char*, int> num;

    num["ten"] = 10;

    num["hundred"] = 100;

 

    for each( pair<const char*, int> c in num )

    {

        Console::WriteLine(gcnew String(c.first) + c.second.ToString());

    }

 

 

    // 해쉬 테이블

    Hashtable^ ht = gcnew Hashtable();

    ht["aaa"] = "111";

    ht["bbb"] = "222";

    for each(DictionaryEntry^ dic in ht)

    {

        Console::WriteLine(dic->Key->ToString() + dic->Value->ToString());

    }

    

 

    getchar();

    return 0;

}

'C++/CLI' 카테고리의 다른 글

[Step. 15] static 생성자, initonly, literal  (1) 2010.09.24
[Step. 13] parameter array  (1) 2010.09.10
[Step. 11] 열거형( enum )  (2) 2010.08.27
[Step. 10] 이벤트 ( event )  (0) 2010.08.20
[Step. 09] 델리게이트 (delegate)  (2) 2010.08.12

[Step. 11] 열거형( enum )

C++/CLI 2010. 8. 27. 09:00 Posted by 알 수 없는 사용자


비관리 코드의 열거형

 

비관리 코드에서 열거형을 정의할 때는 다음과 같습니다.

 

enum WEAPON_TYPE

{

GUN = 1,

SWORD = 2,

BOW = 3

};

 


열거형은 정수형으로 int 형에 대입할 수 있습니다.

int nUsedWeapon = GUN;

 

그런데 저는 위의 방식으로 사용할 때 ‘GUN’이라고 사용하기 보다는 ‘GUN’이 어떤 열거형에 속하는지 표시할 수 있도록 좀 더 다른 방식으로 사용하고 있습니다.

 

struct WEAPON

{

enum TYPE

{

GUN = 1,

SWORD = 2,

BOW = 3

};

};

 

int nUsedWeapon = WEAPON::GUN;

 

이렇게 저는 열거형을 조금 이상한 방법으로 사용하고 있는데 C++/CLI에서는 그럴 필요가 없어졌습니다. C++/CLI는 제가 딱 원하는 방식을 정식으로 지원하고 있습니다.

 


 

C++/CLI의 열거형

 

enum class WEAPON

{

   GUN = 1,

SWORD = 2,

BOW = 3

};

 

int nUsedWeapon = static_cast<int>(WEAPON::GUN);

 

C++/CLI의 열거형은 비관리코드와 비교해서 다른 점은 위에서 알 수 있듯이 암묵적으로 int 형에 대입할 수 없습니다. 왜냐하면 열거형은 정수형이 아니고 object이기 때문입니다.

그래서 캐스팅을 해야 합니다.

 

그리고 C++/CLI의 열거형은 정수형을 명시적으로 정할 수 있습니다.

enum class WEAPON : short

{

   GUN = 1,

SWORD = 2,

BOW = 3

};

 


< 추가 > - 2010. 12. 10

VC++10에서 열거형의 타입을 바로 위의 코드와 같이 명시적으로 지정해도 사용할 수가 없습니다.

enum을 사용할 때 타입 캐스팅을 해야합니다. 왜 이런지 저도 자세한 이유는 모르겠습니다.

C++/CLI에서는 enum 보다는 literal을 사용하는 것이 더 좋을 것 같다고 생각합니다.


public ref class WEAPON
{
public:
        literal short GUN = 1;
        literal short SWORD = 2;

        literal short BOW = 3;

};




참고

http://msdn.microsoft.com/ko-kr/library/ms235243.aspx

 

 

 



'C++/CLI' 카테고리의 다른 글

[Step. 13] parameter array  (1) 2010.09.10
[Step. 12] for each  (1) 2010.09.03
[Step. 10] 이벤트 ( event )  (0) 2010.08.20
[Step. 09] 델리게이트 (delegate)  (2) 2010.08.12
[Step. 08] 프로퍼티 ( property )  (8) 2010.08.06

[Step. 10] 이벤트 ( event )

C++/CLI 2010. 8. 20. 09:00 Posted by 알 수 없는 사용자
이벤트는 그 이름처럼 이벤트를 처리할 때 사용하는 것으로 델리게이트와 조합하여 사용합니다.

보통 이벤트를 설명할 때 button 클래스를 예제로 사용하므로 저도 이것을 사용하여 간단하게 설명하겠습니다.^^

button 클래스의 여러 이벤트 중 clicked 이벤트를 구현할 때 이벤트로 불러질 클라이언트는 OnClick()이라는 멤버함수를 정의한 후 이것을 button 클래스의 clicked에 등록합니다.

 

delegate void ClickHandler();
ref class button {
public:
    event ClickHandler^ Clicked;
    button() {
        btnForTest = this;
    }
public:
    void someoneclicked() {
        Clicked();
    }
    static button^ btnForTest;
};

ref class Client {
private:
    button^ btn;
public:
    Client() {
        btn = gcnew button;
        btn->Clicked += gcnew ClickHandler(this, &Client::OnClick);
    }
private:
    void OnClick() {
        Console::WriteLine("someone clicked.");
    }
};
int main()
{
    Client^ client = gcnew Client;
   
button::btnForTest->someoneclicked();
    return 0;
}
< 출처 : http://cppcli.shacknet.nu/cli:event >
 
 
event는 몇 개의 제약이 있습니다. 
1. Clicked 호출은 button 밖에 할 수 없습니다. 
2. 클라이언트가 Clicked에 대한 조작은 += -=만 할 수 있으며 Clicked() Clicked = nullptr 같은 
것은 할 수 없습니다.
 
 
참고
http://cppcli.shacknet.nu/cli:event






[Step. 09] 델리게이트 (delegate)

C++/CLI 2010. 8. 12. 09:30 Posted by 알 수 없는 사용자
델리게이트는 비관리코드에서는 함수 포인터와 같은 기능을 합니다.

 

#include <iostream>

delegate void TestDelegate();

ref class TEST

{

public:

void TestMethod()

{

  System::Console::WriteLine(“TEST::TestMethod()”);

}

};

 

int main()

{

TEST^ test = gcnew TEST();

TestDelegate^ testDelegate = gcnew TestDelegate( test, &TEST::TestMethod );

 testDelegate();


 getchar();

    return 0;

};

 

 

정적 멤버함수의 델리게이트

 

#include <iostream>

 delegate void TestDelegate();

 ref class TEST

{

public:

static void TestMethod()

{

  System::Console::WriteLine(“TEST::TestMethod()”);

}

};

 

int main()

{

TestDelegate^ testDelegate = gcnew TestDelegate( &TEST::TestMethod );

 

testDelegate();

 

getchar();

return 0;

};

 

 

복수 개의 델리게이트

 

델리게이트는 하나가 아닌 여러 개를 설정할 있습니다.

 

#include <iostream>

delegate void TestDelegate();

 

ref class TESTA

{

public:

void TestMethod()

{

  System::Console::WriteLine(“TESTA::TestMethod()”);

}

};

 

ref class TESTB

{

public:

static void TestMethod()

{

  System::Console::WriteLine(“TESTB::TestMethod()”);

}

};

 

ref class TESTC

{

public:

void operator()()

{

  System::Console::WriteLine(“TESTC::operator()”);

}

};

 

int main()

{

TestDelegate^ testDelegate;

TESTA testA;

TESTC testC;

 

testDelegate = gcnew TestDelegate( testA, &TESTA::TestMethod );

testDelegate += gcnew TestDelegate(&TESTB::TestMethod );

testDelegate += gcnew TestDelegate( testC, &TESTC::operator );

 

testDelegate();

 

getchar();

return 0;

};

 

 

델리게이트의 비교와 삭제

 ==으로 델리게이트를 비교하면 이것은 핸들의 비교가 아닌 델리게이트가 가지고 있는 함수를 비교하는 것입니다. -=을 사용하여 설정한 델리게이트를 제거할 수도 있습니다.

using namespace System;

delegate void MyDele(int);


void func1(int i)

{

    Console::WriteLine("func1");

}


void func2(int j)

{

    Console::WriteLine("func2");

}


int main()

{

    MyDele^ dele;

    dele += gcnew MyDele(&func1);

    dele += gcnew MyDele(&func2);

    MyDele^ dele2 = gcnew MyDele(func1);

    dele2 += gcnew MyDele(&func2);

    if ( dele == dele2 )  {

        Console::WriteLine("TRUE");

    } else {

        Console::WriteLine("FALSE");

    }

   

    dele -= gcnew MyDele(&func1); 

   

    dele(1); 

   

   return 0;

}

< 예제 출처 : http://cppcli.shacknet.nu/cli:delegate >

 

위의 예의 델리게이트들은 모두 void를 반환하고 파라미터가 없는 것인데 당연하듯이 반환 값이나 파라미터를 가질 수 있습니다.




델리게이트의 비동기 실행

 

델리게이트는 비동기 실행을 지원합니다. 비동기 실행은 처리를 요청한 후 종료를 기다리지 않은 호출한 곳으로 제어를 넘겨줍니다. 델리게이트 함수가 긴 시간을 필요로 하는 작업인 경우 비동기 실행을 이용하면 프로그램의 응답성을 높일 수 있습니다.

 

델리게이트의 비동기 실행은 스레드를 사용합니다. 이런 경우 비동기 실행을 할 때마다 스레드의 생성과 소멸에 부담을 느낄 수도 있지만 델리게이트는 닷넷의 기능을 잘 활용하여 스레드를 생성/삭제하지 않고 스레드 풀에 있는 스레드를 사용하므로 스레드 사용에 대한 부담이 작습니다.

 

비동기 실행을 할 때는 주의해야 할 점이 있습니다. 비동기 실행을 하는 경우 델리게이트에는 꼭 하나의 함수만 등록해야 합니다. 만약 2개 이상 등록하였다면 예외가 발생합니다.

 

비동기 실행은 BeginInvoke()를 사용하고, 만약 종료를 기다리고 싶다면 EndInvoke()를 사용합니다.

 

#include "stdafx.h"

#include <iostream>

 

using namespace System;

 

delegate void MyDele(void);

 

void myfunc(void)

{

    System::Threading::Thread::Sleep(3000);

}

 

 

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

{

     MyDele^ dele = gcnew MyDele(&myfunc);

            Console::WriteLine(L"1");

     IAsyncResult^ result = dele->BeginInvoke(nullptr,nullptr);

            Console::WriteLine(L"2");

    dele->EndInvoke(result);

            Console::WriteLine(L"3");

   

    getchar();

    return 0;

}

 

위 코드를 실행하면 '2'가 찍힌 이후 3초가 지난 이후에 3이 찍힙니다.





참고
http://cppcli.shacknet.nu/cli:delegate
http://cppcli.shacknet.nu/cli:delegate%E3%81%9D%E3%81%AE2



[Step. 08] 프로퍼티 ( property )

C++/CLI 2010. 8. 6. 09:30 Posted by 알 수 없는 사용자

보통 비관리 클래스를 정의할 때 캡슐화를 위해서 멤버 변수는 최대한 private 접근으로 한 후 외부에서의 접근을 위해서 get set 멤버 함수를 정의합니다.

 

class Character

{

public:

…….

   void SetCharCd( const int nCharCd ) { m_nCharCd = nCharCd; }

   int GetCharCd() { return m_nCharCd; }

…….

private:

   int m_nCharCd;

   …….

};

 


클래스의 멤버를 하나 정의할 때마다 그에 대응하는 get, set 멤버 함수를 정의하는 것은 좀 귀찮은 일이기도 합니다. 그래서 관리코드에서는 이 작업을 쉽게 해주는 property가 생겼습니다.

 

ref class Character

{

public:

…….

    property int CharCd

{

   void set( int nCharCd ) { m_nCharCd = nCharCd; }

   int get() { return m_nCharCd; }

}  

…….

private:

   int m_nCharCd;

   …….

};

 

위 코드에서는 get set을 둘 다 정의 했는데 둘 중 하나만 정의 해도 괜찮습니다.

또 위의 set은 아주 간단하게 그냥 대입만 하고 있는데 좀 더 로직을 넣을 수도 있습니다.

 

ref class Character

{

public:

…….

    property int CharCd

{

   void set( int nCharCd )

{

  if( nCharCd < 0 ) {

     m_nCharCd = 0;

  } else {

     m_nCharCd = nCharCd;

  }

}

 

   int get() { return m_nCharCd; }

}  

…….

private:

   int m_nCharCd;

   …….

};

 

 


property 선언과 정의 나누기


일반적으로 클래스의 멤버 선언은 헤더 파일에 정의는 cpp 파일에 하듯이 property도 선언과 정의를 나눌 수 있습니다.

 

ref class Character

{

public:

…….

    property int CharCd

{

   void set( int nCharCd );

   int get();

}  

…….

private:

   int m_nCharCd;

   …….

};

 

 

void Character::CharCd::set( int nCharCd )

{

if( nCharCd < 0 ) {

m_nCharCd = 0;

} else {

   m_nCharCd = nCharCd;

  }

}

 

void Character::CharCd::get()

{

return m_nCharCd;

}

 



 

get set의 접근 지정자 다르게 하기

 

위에서 property를 정의할 때 get set은 모두 public 였습니다.

이것을 각각 다르게 접근 지정자를 정할 수 있습니다.

 

ref class Character

{

public:

…….

    property int CharCd

{

protected:

   void set( int nCharCd )

{

  if( nCharCd < 0 ) {

     m_nCharCd = 0;

  } else {

     m_nCharCd = nCharCd;

  }

}

 

    public:

   int get() { return m_nCharCd; }

}  

…….

private:

   int m_nCharCd;

   …….

};

 

 

 

 

참고

http://cppcli.shacknet.nu/cli:property

http://vene.wankuma.com/prog/CppCli_Property.aspx

 

 

[Upgrade to VC++ 10] _WIN32_WINNT 버전 문제

Visual C++ 10 2010. 8. 2. 09:00 Posted by 알 수 없는 사용자

VS.NET(VS2002)에서 MFC 프로젝트로 만들었던 프로그램을 VC++10 프로젝트로 변환하여 컴파일 했더니 에러가 발생하면서 아래의 경고가 나왔습니다.

 

C:\Program Files\Microsoft Visual Studio 10.0\VC\atlmfc\include\atlcore.h(35):#error This file requires _WIN32_WINNT to be #defined at least to 0x0403. Value 0x0501 or higher is recommended.

 

에러 내용은 프로젝트에서 정의된 _WIN32_WINNT 버전이 0x403인데 atlcore.h 버전이 최소 0x0501 이상이 되어야 한다는 것입니다.

 

그래서 _WIN32_WINN 정의한 stdafx.h 파일을 열어보니

#define _WIN32_WINNT 0x0400

되어 있었더군요. 그래서 일단 이것을 최신이 좋다라는 생각에 아래와 같이 했습니다. ^^;;

#define _WIN32_WINNT 0x0600

 

그랬더니 이제는 아래와 같은 에러가 나오더군요. -_-;

c:\program files\microsoft visual studio 10.0\vc\atlmfc\include\afxcmn3.inl(29): error C2065: 'CCM_SETWINDOWTHEME' : 선언되지 않은 식별자입니다.

 

그래서 바로 구글링 들어갔습니다.

쉽게 저와 같은 에러가 나와서 질문을 올린 글을 찾았고 답변도 보았습니다.

문제 해결은 stdafx.h 파일에 정의된 버전의 숫자를 아래와 같이 하면 된다고 하더군요

// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.
#define WINVER 0x0501 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif

#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif

#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
#define _WIN32_WINDOWS 0x0501 // Change this to the appropriate value to target Windows Me or later.
#endif

#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.
#define _WIN32_IE 0x0500 // Change this to the appropriate value to target IE 5.0 or later.
#endif

 

이렇게 하니 문제 없이 빌드가 성공 되었습니다.

 

주위에서 VC++의 새로운 버전이 나와도 쉽게 사용하지 못하는 경우가 오래 전에 만들었던 프로젝트를 포팅 할 수 없어서 이전 버전을 어쩔 수 없이 사용한다는 이야기를 종종 듣습니다.

그러나 저는 운이 좋아서인지 2002버전부터 순차적으로 새 버전의 VC++을 사용할 수 있어서 VC++6에서 VS2002로 넘어갈 때만 빌드 문제를 겪었습니다.

그래서 이런 포팅에 대한 문제는 잘 알지 못합니다. 이번에는 예전에 만들었던 코드를 C++0x 코드로 바꾸고 싶어서 오래 전에 만들었던 프로젝트를 VC++ 10로 포팅하면서 정말 정말 오랜만에 이런 문제를 겪어 보게 되고 해결 방법을 포스팅 할 수 있었습니다.

 

혹시 앞으로 또 이런 경우가 발생하면 바로 바로 공유하도록 하겠습니다.  





Visual C++ 10의 변화

Visual C++ 10 2010. 5. 2. 22:08 Posted by 알 수 없는 사용자

영문판 VS 2010(Visual C++ 10)은 나왔고, 한글판은 61일에 나온다고 합니다.

 

Visual C++ 10을 도입하려고 하시는 분들은 전체적으로 어떤 변화가 있는지 알고 싶을 것이고, 특히 구매를 위해 회사 윗 분들에게 보고를 해야 되는 분들은 관련된 문서를 만들어야 하는 분들도 있으리라 생각합니다.

 

VC++ 10 도입이나 내부 스터디에 사용하도록 간단하게 VC++ 10의 달라진 점을 정리하여 문서를 만들어 보았습니다.

 

이 문서는 러프하게 만들어진 문서이니 참고로 사용하여 더 좋은 문서를 만드시기를 바랍니다. 특히 윗 분들에게 보고 하기 위해서 PT문서를 만들 때는 이 문서에 왜 필요한지에 대해서 좀 더 강력한 메시지를 넣기를 바랍니다.^^






VC++ 10에 구현된 C++0x의 코어 언어 기능들

C++0x 2010. 4. 12. 08:30 Posted by 알 수 없는 사용자

Visual C++ 팀 블로그에 C++0x Core Language Features In VC10: The Table라는 이름으로 C++0x의 기능 중 코어 언어와 관련된 것 중에서 VC++ 10에 구현된 것들을 테이블 표로 정리되어 있습니다.

GCC C++0x 구현 항목 테이블 표 형식을 차용했다고 하네요.


 

 

위의 테이블 표에서는 C++0x가 처음 구현된 VC++9VC++ 10을 비교하고 있습니다.

 

그리고 글의 마지막에 작년에 Boost Con(Boost 라이브러리 관련 행사)에서 발표한 자료가 첨부 파일로 있습니다. 이 문서를 보면 VC++ 10에서 구현한 C++0x의 코어 언어 기능들을 설명하고 있습니다.

 

문서를 보니 큰 기능들은 제가 작년부터 공부하면서 저희 팀 블로그나 여러 장소에서 설명 하였지만 일부 기능은 저도 미쳐 파악 하지 못한 것들도 있더군요. 앞으로 이런 빠진 부분에 대해서 팀 블로그를 통해서 설명해 드리겠습니다.^^


 

'C++0x' 카테고리의 다른 글

[Plus C++0x] 람다(Lambda) 이야기 (2)  (1) 2010.05.27
[Plus C++0x] 람다(Lambda) 이야기 (1)  (0) 2010.05.27
"Visual C++ 10과 C++0x" pdf 파일  (4) 2010.04.20
C++0x 관련 책 "Visual C++ 10과 C++0x"  (9) 2010.04.17
nullptr  (2) 2010.01.28