Visual Studio 2010 공식 팀 블로그 @vsts2010

Posted by 흥배

요즘 바쁘다 보니 아주 오랜만에 글을 올리게 되었습니다^^;

이번 시간에는 chrono를 사용하여 시간 계산에 대해서 간단하게 설명 하겠습니다.

 

이전 시간에서 보았듯이 chrono는 아래와 같이 다양한 타입으로 시간을 표시할 수 있습니다.

 

boost::chrono::nanoseconds  // 나노 세컨드. 10억분의 1

boost::chrono::microseconds // 마이크로 세컨드. 100만분의 1

boost::chrono::milliseconds  // 밀리 세컨드. 1000분의 1

boost::chrono::seconds      //

boost::chrono::minutes      //

boost::chrono::hours        //

 

 

각 시간 타입 별로 생성할 때 값을 설정할 수 있습니다.

boost::chrono::hours H1(1); // 1시간

boost::chrono::hours H2(2); // 2시간

boost::chrono::hours H25(25); // ?

 

boost::chrono::seconds S1(10);

boost::chrono::seconds S2(120);

 

boost::chrono::milliseconds MILS1(100);

 위 코드의 H1이나 S1, MILS1은 문자열이나 숫자로 출력할 수 있습니다.(방법은 제일 아래의 예제 코드를 봐 주세요)

 

또한 이 시간 타입을 서로 연산할 수도 있습니다.

boost::chrono::hours H1(1);

boost::chrono::hours H2(2);

boost::chrono::hours H3 = H1 + H2;

 

물론 다른 시간 타입을 연산할 수도 있습니다

boost::chrono::seconds S1(10);

boost::chrono::milliseconds MILS1(100);

boost::chrono::milliseconds MILS2 = S1 + MILS1;

 

다른 시간 타입을 연산할 때 주의할 점이 있습니다. 아래처럼

boost::chrono::milliseconds MILS2 = S1 + MILS1;

의 경우는 초와 밀리세컨드라는 서로 다른 타입을 더하지만 값을 저장하는 타입이 밀세컨드이기 때문에 읽어버리는 값이 발생하지 않으므로 연산에 문제가 없습니다.

 

그러나 아래와 같이

boost::chrono:: seconds S2 = S1 + MILS1;

로 하는 경우는 밀리세컨드 부분을 잃어버리게 되기 때문에 컴파일 에러를 발생합니다.

이런 경우는 명시적으로 형 변환을 시켜줘야 합니다.

boost::chrono::seconds S2 = boost::chrono::duration_cast< boost::chrono::seconds >(S1 + MILS1);

 


< 예제 >

#include <boost/chrono.hpp>

int main()
{
    {
        boost::chrono::hours H1(1); // 1시간
        boost::chrono::hours H2(2); // 2시간
        boost::chrono::hours H3(25); // ?

        std::cout << "H1(1) - 문자열 : " << H1 << std::endl;
        std::cout << "H1(1) - 숫자로 : " << H1.count() << std::endl;
        std::cout << "H3(25) - 문자열 : " << H3 << std::endl;
        std::cout << "H3(25) - 숫자로 : " << H3.count() << std::endl;


        boost::chrono::seconds S1(10);
        boost::chrono::seconds S2(120);

        std::cout << "S1(10) - 문자열 : " << S1 << std::endl;
        std::cout << "S1(10) - 숫자로 : " << S1.count() << std::endl;

        std::cout << "S2(120) - 문자열 : " << S2 << std::endl;
        std::cout << "S2(120) - 숫자로 : " << S2.count() << std::endl;
    }

    {
        boost::chrono::hours H1(1);
        boost::chrono::hours H2(2);
        boost::chrono::hours H3 = H1 + H2;

        std::cout << "H1 + H2 = : " << H3 << std::endl;


        boost::chrono::seconds S1(10);
        boost::chrono::milliseconds MILS1(100);
        boost::chrono::milliseconds MILS2 = S1 + MILS1;

        std::cout << "S1 + MILS1 = : " << MILS2 << std::endl;


        boost::chrono::seconds S2 = boost::chrono::duration_cast< boost::chrono::seconds >(S1 + MILS1);

        std::cout << "S1 + MILS1 = : " << S2 << std::endl;
    }



    return 0;
}



 

 

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. You are completely right in such kind of technical points!

  2. I was searching for such a guide! It is very much clear to me

Posted by 흥배

chrono는 경과 시간을 계산할 때 다양한 시간 타입으로 계산할 수 있습니다.

이전 회의 예제의 경우는 초 단위로 표시하되 소수점까지 표시할 수 있었습니다.

boost::chrono::duration<double> sec = boost::chrono::system_clock::now() - start;

 

그런데 보통은 소수점이 나오는 결과 값보다는 정수로 나오는 값을 사용하는 경우가 많을 것입니다.

 

chrono에서는 경과 시간을 나타내는 클래스는 duration입니다.

duration 6개의 시간 단위를 지원합니다.

nanoseconds - 10억분의 1

microseconds - 100만분의 1

milliseconds - 1000분의 1

seconds –

minutes -

hours – 시간

 

이전 회의 예제를 사용하여 이번에는 다양한 시간 단위로 경과 시간을 표시해 보겠습니다.

#include <boost/chrono.hpp>

#include <cmath>

 

void Test()

{

           for ( long i = 0; i < 10000000; ++i )

           {

                     std::sqrt( 123.456L );

           }

}

 

int main()

{

    boost::chrono::system_clock::time_point StartTime = boost::chrono::system_clock::now();

                    

    Test();

    boost::chrono::system_clock::time_point EndTime = boost::chrono::system_clock::now();

 

    boost::chrono::duration<double> DefaultSec = EndTime - StartTime;

    boost::chrono::nanoseconds nano = EndTime - StartTime;

    boost::chrono::microseconds micro = boost::chrono::duration_cast<boost::chrono::microseconds>(EndTime - StartTime);

    boost::chrono::milliseconds mill = boost::chrono::duration_cast<boost::chrono::milliseconds>(EndTime - StartTime);

    boost::chrono::seconds sec = boost::chrono::duration_cast<boost::chrono::seconds>(EndTime - StartTime);

    boost::chrono::minutes min = boost::chrono::duration_cast<boost::chrono::minutes>(EndTime - StartTime);

    boost::chrono::hours hour = boost::chrono::duration_cast<boost::chrono::hours>(EndTime - StartTime);

 

    std::cout << "Test() 함수를 수행하는 걸린 시간 : " << DefaultSec.count() << " default" << std::endl;

    std::cout << "Test() 함수를 수행하는 걸린 시간 : " << nano.count() << " nanoseconds" << std::endl;

    std::cout << "Test() 함수를 수행하는 걸린 시간 : " << micro.count() << " microseconds" << std::endl;

    std::cout << "Test() 함수를 수행하는 걸린 시간 : " << mill.count() << " milliseconds" << std::endl;

    std::cout << "Test() 함수를 수행하는 걸린 시간 : " << sec.count() << " seconds" << std::endl;

    std::cout << "Test() 함수를 수행하는 걸린 시간 : " << min.count() << " minutes" << std::endl;

    std::cout << "Test() 함수를 수행하는 걸린 시간 : " << hour.count() << " hour" << std::endl;

                    

    return 0;

}

 

< 결과 >


 


 ps : 네임스페이스를 다 적다보니 코드 가독성이 좀 떨어질텐데 양해바랍니다^^;

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 이 나오는 결과 값보다는 정수로 나오

Posted by 조진현


안녕하세요~ 조진현입니다.
얼마 전 대구에서 KGC 2011 행사가 있었습니다.
저는 그 곳에서 DirectX11 과 관련한 발표를 진행하고 왔습니다.
그래서 발표 슬라이드를 공개해 드립니다.

특히나 이번 발표 때, C++ AMP 에 대한 언급이 있었습니다.
AMP는 아래 링크에 흥배님이 자세히 설명해 주셨습니다.
http://vsts2010.net/591

빠른 시간 내에 발표 때 언급했던 C++ AMP 와 관련한 내용을
팀 블로그에 게재하도록 하겠습니다..^^

[조진현] [Kgc2011]direct x11 이야기
View more presentations from 진현 조.
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 박민근 2011/11/14 17:56

    초상권 사용료를 내놓으셈~

  2. 멋진 발표자료, 잘 보았습니다.

  3. 이것은 위대한 게시물이며 있는지 이것을 사랑하고 이것을 공유 주셔서 감사하려고 많은 사람들이있다

  4. 멋진자료 잘보았습니다. 사실내가 더 멋지지만

  5. 이것은 위대한 게시물이며 있는지 이것

Posted by 흥배

혹시 Boost 라이브러리라는 것을 아시나요? 만약 아직 모르고 있었다면 C++ 프로그래머로서 적지 않은 손해를 보고 있다고 생각합니다.^^

Boost 라이브러리는 C++ 프로그래머를 위한 유용한 오픈 소스 C++ 라이브러리 모음입니다. Boost 라이브러리 개발에 수 많은 C++ 고급 프로그래머들이(C++ 표준 위원회 멤버 등) 참여 하고 있습니다. 그래서 Boost 라이브러리는 실용적인 기능과 높은 안정성을 가지고 있습니다.

 

만약 아직까지 Boost 라이브러리를 한번도 사용해 본적이 없다면 바로 사용하기를 권합니다. 그리고 아직도 일부에서는 Boost 라이브러리의 안정성에 대해서 의심하는 분들이 있는데 무의미한 의심은 그만두기를 바랍니다^^

 

C++11에 들어가는 새로운 표준 라이브러리에는 Boost 라이브러리에 있는 것들이 많이 들어갔습니다. 예를 들면 VS 2008 SP를 설치하면 사용할 수 있는 tr1 라이브러리에 있는 대부분이 Boost 라이브러리에 있는 것입니다. 새로운 표준에는 들어갔지만 아직 VC++에서 지원하지 않는 라이브러리도 Boost 라이브러리를 사용하면 미리 사용해볼 수 있습니다.

 

다음에 소개할 chrono Boost 라이브러리에 이미 있습니다. 그러니 Boost 라이브러리를 설치하면 chrono는 바로 사용해 볼 수 있습니다.

 

Boost 라이브러리의 설치와 사용 방법은 구글링을 하면 적지 않게 찾을 수 있습니다. 그 중 몇 개를 제가 찾아 놓았습니다^^

 

 

Boost 라이브러리 홈페이지

http://www.boost.org/

최신 버전은 1.47.0 입니다.

 

 

VC++ 6.0에서 Boost 라이브러리 설치

- 1.33 버전까지만 설치할 수 있습니다

http://blog.naver.com/sorkelf/40132524363

 

 

설치 파일로 설치하기 (VC++ 7.1 ~ VC++ 10까지 지원)

- Boost 라이브러리는 대부분의 기능은 헤더 파일 추가만으로 사용할 수 있지만 일부 기능(thread, filesystem ) lib 파일을 만들어야 합니다. 그러나 설치 파일로 설치하면 이미 빌드된 lib 파일을 얻을 수 있습니다.

http://ncanis.tistory.com/333

 

 

수동으로 설치하기

- 가장 기본 적인 방법으로 직접 lib 파일을 만들어야 합니다. 위의 설치 파일보다 장점은 lib 파일을 빌드할 때 옵션을 마음대로 지정할 수 있고, 특히 가장 최신 버전을 빨리 사용할 수 있습니다.

http://genkino.tistory.com/1446

 

 

Boost 라이브러리 설명

- 몇 년 전에 제가 번역한 것으로 1.33 버전을 기준으로 하고 있습니다. 설명에 부족한 것이 많지만 그런 부분은 구글링을 찾아보시기 바랍니다.

http://jacking75.cafe24.com/Boost/libraries.htm

 

 

Boost 라이브러리 e-book

- 영어라는 단점(?)이 있지만 각 기능을 잘 설명하고 있습니다.

http://en.highscore.de/cpp/boost/

 


꼭 Boost 라이브러리를 설치하고 사용하기를 강력하게 추천합니다

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 가장 기본 적인 방법으로 직접 lib 파일을 만들어야 합니다

Posted by 흥배

unscoped enumeration scoped enumeration

C++11(새로운 C++ 표준의 이름) enum은 지금(C++03)과 다르게 두 가지의 enum이 있습니다.

바로 unscoped enumeration scoped enumeration 입니다.

 

unscoped enumeration은 기존의 enum과 비슷한 것 이라고 생각 하면 되고, scoped enumeration C++11에서 새로 생긴 enum 입니다.

 

unscoped enumeration은 아래와 같이 정의하고 사용합니다.

enum ITEMTYPE : short

{

   WEAPON,

   EQUIPMENT,

   GEM       = 10,

   DEFENSE,  // C++03까지는 에러이지만 C++11에서는 에러가 아님

};

 

사용은 아래와 같이

short ItemType = WEAPON;

또는

short ItemType = ITEMTYPE::WEAPON; // C++03에서는 에러

 

 

scoped enumeration은 아래와 같이 정의하고 사용합니다.

enum class ITEMTYPE : short

{

   WEAPON,

   EQUIPMENT,

   GEM       = 10,

   DEFENSE, 

}

 

사용은 아래와 같이 합니다.

short ItemType = ITEMTYPE::WEAPON;

그러나 아래는 에러입니다.

short ItemType = WEAPON;  // 에러

 

scoped enumeration unscoped enumeration와 다르게 ITEMTYPE를 생략하면 안됩니다. WEAPON이나 GEM ITEMTYPE의 범위 안에 있음을 가리킵니다.

그리고 enum class 대신 enum struct을 사용해도 괜찮습니다. 또 타입을 지정하지 않으면 기본으로 int 타입이 됩니다.

 

 

 

전방 선언

unscoped enumeration scoped enumeration 둘 다 전방 선언을 할 수 있습니다.

 

아래와 같이합니다.

enum ITEMTYPE : short;

enum class ITEMTYPE : short;

 

전방 선언을 할 때 unscoped enumeration은 타입 선언을 생략할 수 없지만 scoped enumeration은 타입 선언을 생략 할 수 있습니다.

 

 

 

형 변환

unscoped enumeration은 기존과 같이 암묵적으로 정수로 변환할 수 있습니다.

int i = WEAPON;

그러나 scoped enumeration은 명시적으로 타입 캐스팅을 해야합니다.

int i = static_cast<int>(ITEMTYPE::WEAPON);

 

 

 


참고

http://d.hatena.ne.jp/spinor/20110918/1316321563

 


저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 실질적으로, 기사는이 칭찬할만한 주제에 정말 최고입니다. 당신의 결론에 동의하고 열심히 미래의 업데이 트를 기대합니다. 그냥 당신이 그냥 서면으로 멋진 명석을 위해 충분하지 않습니다 감사합니다라고. 나는 즉시 만족 일과 비즈니스 노력에 많은 성공을 것입니다.

  2. 래의 업데이 트를 기대합니다. 그냥 당신

  3. 대법원은 그중 이미 중요한 부분 및 마케팅 전략의 주요 기반 중 하나가 발생했습니다. 현재, 사람들은 옵션의 충분한로 취급되었다. 인터넷을 통해 선택은 다시 성장하고있다.

  4. 경험을 바탕으로 좋은 홍보 자료가 너무 좋은 판매량을 높일 것입니다. 당신은 나쁜 판촉물 경우, 즉시 변경합니다. 기업의 많은이 새로운 사업을 구축할 오래 생각해야하지만, 뒤얽힌 때 판촉 비용이 없습니다.

  5. 기존 고객 유지는 새로운 고객을 찾는 데보다 훨씬 저렴합니다. 성공적인 비즈니스는 고객과의 관계를 구축하기 위해 노력 시작해야합니다.

  6. 이메일 마케팅은 회사와 클라이언트 간의 관계의 모든 측면을 측정할 수있는 유일한 기회입니다. 이메일 마케팅은 중요한 벡터 생성 웹 트래픽입니다. 판촉 모델의 상단 목록에서 많은 마케팅 이메일 마케팅 장소. 사용하는 전자 메일 마케팅 무게 그룹이 직접적인 마케팅 캠페인을 이동됩니다 찾는 정확하게 구성되어 있습니다.

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을 잘 사용하면 기존 보다 더 뛰어난 프로그래밍을 할 수 있으니 깊게 파고들 가치가 있다고 생각합니다.

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 일 할 때 결과가 이미 결정 나는 것은 컴파일 타임 때 처

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 );



 

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 시에 정수가 되기 때문에 변수 선언 시 대입이 정

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

 

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. final 저건 맘에 드네요. 지금까진 따로 __final___ 이라고 define 해서 썼는데. JAVA를 아는 사람이면 알아보리라는 기대감과 함께...

    근데 override 에서 virtual 키워드의 설명은 귀찮아서 대강 적으신듯. virtual 을 안써도 override 의 개념이긴 한데, 하긴 virtual 을 간단히 설명하기가 좀 애매하군요.

  2. override가 c++11에서 표준이 된건가요?

    기존에 vs2008에서 MS가 제공해주는 키워드인걸로 알고 있어서
    보기도 편하고 실수를 줄일수있어서 사용하던건데.....

    표준이 된거라면 환영~^^

  3. final 은 sealed 와 다른건가요?

    • 제가 알기로 sealed는 주로 자바와 C#에서 사용하는 것으로 알고 있는데 sealed는 다른 클래스가 이 클래스를 상속 하지 못하게 하는 것이고, final은 부모 클래스의 특정 멤버함수를 오버라이드 하지 못하게 하는 것입니다.

  4. 보기도 편하고 실수를 줄일수있어서 사

  5. 참조은 당신의 서비스 또는 제품을 사용할 수있을 그가 아는​​ 사람을 걱정하는 고객을 청할 때가 아닌 다른 누구도 없었다. 이 참조의 주요 아이디어는 사람이 참조된 연락을하는 것입니다.

  6. 허가 기반의 마케팅은 온라인 커뮤니케이 션에 추진 새 규칙이며, 당신이 말한 것을 관심을 자신의 중심에 따라 회사에서 상업용 전자 메일을 수신 안내서를 얻어 기반으로합니다.

  7. 어머니 또는 아버지는 젊은이의 필요성을 제공합니다.아이의 필요성은 시간이 지남에 많은 지네요. 그들은 모두 현금으로 준비한다.

  8. 모든 부모는 아이에게 장점을 제공합니다. 당신의 아이들은 최고의 수신을 직접 특정을 가지고. 젊은이를위한 가장 좋은 고가 하나의 특정 아닙니다.

  9. 부모는 아이들의 필요를 제공할 것입니다.아이들의 필요 년까지 많은 년을 받고있다. 그들은 돈으로 준비를해야합니다.

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

 

 

 

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 내가? 그는 웹 사이트에 배포 꽤 제안을 발견으로 친구에게서 전화를 얻는 특권을 해요. 블로그 게시 주변 서핑하는 것은 일반적으로 정품 멋진 만남이다. 자신에 비해 어떤 측면에서 고객을 고려하고 많은 덕분에, 난 당신에게 전문 영역 것으로 승리와 관련된 최선을 열망.

  2. 려하고 많은 덕분에, 난 당신에게 전문 영

  3. 개인적으로 도서관에 와서 그것을 다운로드하여 직접 집에서 읽어 않고도 바로 거기에 책을 읽는 것을 선호합니다. 나는 도서관 상황은 조용하고 시원하고 편안한 사랑 해요.

  4. 감사의 뜻을 전달하기 위해, 우리는 특정 목표를 달성하기 위해 전세기 예약을 위해 신용 카드를 사용합니다. 그것은 고객이 제품을 구입하는 동기를 부여하실 수 있습니다.

  5. 이메일 마케팅은 회사와 클라이언트 간의 관계의 모든 측면을 측정할 수있는 유일한 기회입니다. 이메일 마케팅은 중요한 벡터 생성 웹 트래픽입니다. 판촉 모델의 상단 목록에서 많은 마케팅 이메일 마케팅 장소.

  6. 경력은 평범한 사람이 만족하는 무언가가 될 수 있습니다.성공 종래는 작업에서 볼 수 있습니다. 때때로, 사람들은 직업의 일부 형식을 무시합니다.

  7. 언어를 프로그래밍하는 것은 배울 매우 중요하는 것은 웹사이트를 개발하려는 것입니다. 그것은 처음에 매우 어려운 것입니다.

  8. 때때로 일이 일이 남자와 여자가 ​​펄럭 다네.경력은 남성과 여성들이 더 많은 수업을 잘하고, 믿게 수 있습니다. 그럼에도 불구하고 작업의 품질과 남성과 여성 행복하게 그 일을해야합니다.

  9. 직업은 그 사람들이 자랑스러운 일이 될 수 있습니다.번영의 기준은 작업에서 볼 수 있습니다. 때때로, 사람들은 일자리 특정 종류의 과소 평가.

Posted by 조진현

 

 

Direct2D 리소스( Resource ) 기본 개념

 

Direct2D 에서 리소스라는 것은 단지 메모리를 의미합니다.

그 메모리는 지오메트리(Geometry)나 비트맵 이미지가 될 수도 있습니다.

즉, 이들 리소스는 메모리들이 추상화 된 일종의 개념적인 분류들입니다.

 

이들 리소스를 처리해서 모니터에 최종적으로 보여주는 것이 Direct2D의 역할입니다.

이전 까지 사용되던 GDI 도 바로 이런 역할을 하는 것입니다.

 

하지만, GDI와 Direct2D 는 리소스 처리 방식이 완전히 다릅니다.

앞선 시간을 통해서, GDI는 CPU만을 활용한다고 꾸준히 언급했습니다.

 

반면에, Direct2D는 CPU와 GPU를 동시에 활용합니다.

CPU와 GPU를 동시에 활용하기 때문에,

리소스들도 이들에 맞게 추상적으로 재분류 되어야 합니다.

 

Direct2D는 이 리소스들을 크게 두 가지 형태로 분류합니다.

바로 디바이스 독립적인 리소스( device-independent resource )와

디바이스 의존적인 리소스( device-dependent resource )로 분류하고 있습니다.

이들 두 리소스들은 모두 ID2D1Resource 인터페이스를 상속받습니다.

 

 

디바이스 독립적인 리소스

 

디바이스 독립적인 리소스라고 하는 것은 CPU에 의해서 처리되는 리소스를 의미합니다.

단어 자체에서 볼 수 있듯이,

이들 리소스는 사용자의 그래픽 하드웨어와 상관없는 처리 결과를 보장합니다.

 

뒤에서 살펴보겠지만, 지오메트리를 표현하는 인터페이스들이 여기에 속합니다.

( 조금 더 정확히 나열하면, ID2D1DrawingStateBlock, ID2D1Factory, ID2D1Geometry,

ID2D1GeometrySink, ID2D1SimplifiedGeometrySink, ID2D1StrokeStyle 등이 여기에 속합니다. )

아래는 이런 디바이스 독립적인 리소스들의 계층구조를 보여주는 그림입니다.

 

 

 

 

 

디바이스 의존적인 리소스

 

반면에 디바이스 의존적인 리소스는 GPU에 의해서 처리되는 리소스를 의미합니다.

사용자들이 가지고 있는 그래픽 하드웨어들은 매우 다양하기 때문에, 그 기능들을 모두 동일한 방식으로 처리하는 것이 쉽지 않습니다.

( 각각의 하드웨어마다 성능이나 명령어들이 모두 차이가 나기 때문이겠죠..^^ )

즉, 이들은 사용자의 하드웨어들에 따라서 결과가 차이가 날 수 있습니다.

이 차이라는 것은 눈으로 확인 가능한 차이를 얘기하는 것이 아니라,

그래픽 하드웨어들이 생성하는 명령어들과 성능 등과 같은 차이를 얘기하는 것입니다.

 

우리가 보는 모니터는 그래픽 하드웨어들이 생성한 명령어들의 최종적인 결과입니다.

리소스들도 바로 이 그래픽 하드웨어의 영향을 받아서 결과가 생성되는 것입니다.

 

앞서 우리가 화면에 렌더링 하기 위해서 만들었던 렌더타겟이나 브러시, 이미지 같은 리소스들은 모두 여기에 속합니다.

아래의 그림은 디바이스에 의존적인 리소스들의 계층구조를 표현하는 그림입니다.

 

 

 

 

Direct2D는 리소스 처리 방식은 되도록이면 GPU를 활용합니다.

GPU 처리가 불가능하다면, 자동적으로 CPU로 처리하게 됩니다.

GPU를 활용하는 리소스라면, 더욱 높은 품질로 빠르게 처리할 수 있습니다.

 

이들 리소스에 대한 설명은 다음 시간부터 차근히 살펴보겠습니다.^^

 

크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 들 리소스에 대한 설명은 다음 시간부

Posted by 조진현

 

  

이번 시간에는 직접 이미지를 화면에 표현하는 방법에 대해서 언급합니다.

Win32 API를 이용할 때, 우리는 '비트맵(Bitmap)' 이라는

그래픽 데이터 포맷을 읽어서 화면에 그려주었습니다.

사람마다 차이는 있겠지만, 일반적으로 다음과 같은 순서를 따라서 구성했을 것입니다.

 

  1. 비트맵을 읽기 위해서 파일을 오픈한다.

  2. 파일에서 헤더를 읽어 들인다.


  3. 비트맵 헤더의 정보를 통해서 관련 메모리를 생성하고,

    파일에서 색상 데이터에 대한 정보를 읽는다.


  4. DIBSection 을 생성하고, 실제 데이터를 읽는다.
  5. 그리고 마무리 한다.

 

이 순서는 수 많은 방법 중에 하나일 뿐이지만,

기본적으로 파일을 열어서 헤더를 먼저 읽고, 관련 메모리를 생성하고,

이후에 실제 데이터를 채우게 되는 순서는 공통된 작업입니다.

Direct2D 에서도 이와 같이 작업을 해도 되지만,

이미 편의를 위해 만들어진 라이브러리를 사용해서 조금 더 확장성 있는 작업을 할 필요가 있습니다.

지금부터는 WIC를 이용한 간단한 이미지 뷰어 작업을 해보겠습니다.

  

WIC( Windows Imaging Component )

 

DirectX 가 윈도우 운영체제 전반으로 광범위하게 활용되면서,

이들과 관련한 내용들을 분리할 필요가 있었습니다.

과거까지는 DirectX 는 게임 개발자들의 전유물에 가까웠기 때문에,

다른 개발자들도 손쉬운 개념으로 접근할 수 있는 그런 분류가 필요했습니다.


결과적으로 아래와 같이 분류가 되었습니다.  

 

WIC는 모든 이미지를 쉽게 처리할 수 있도록 만들어낸 COM 기반의 프레임워크입니다.

그림에서 보듯이 WIC도 하나의 큰 영역으로서 자리 잡고 있습니다.

( 참고로 DXVA는 영상 처리를 위한 프레임워크입니다. )

 

WIC를 이용한 이미지 처리는 앞서 GDI 기반에서 작성했던 것과는 완전히 다릅니다.

WIC는 PNG, JPG, GIF 등과 같은 거의 모든 주요한 이미지 형식을 포함하고,

기본 코덱들을 지원하고 있습니다.

 

말이 참 어렵죠?

쉽게 말해서, Direct2D 기반에서 이미지 처리를 하려면 WIC를 사용하면 쉽게 할 수 있다는 것입니다.

우리는 이것을 사용하는 순서와 방법에 대해서 배우기 위해서,

윈도우 화면에 이미지를 그려주는 간단한 애플리케이션을 만들어 볼 것입니다.

 

 

기본 WIC 프로그래밍

 

애플리케이션 마법사로 새로운 프로젝트를 만들고, stdax.h 에 다음을 추가를 합니다.

 

'WindowsCodecs.lib'와 'wincodec.h' 가 바로 WIC를 사용하기 위해 추가시킨 것입니다.

눈치 빠른 분들이라면, 이름에서 약간 앞으로의 작업 방향을 예측할 수 있을 것입니다.

 

이번 프로젝트에서 사용할 전역 변수들은 아래와 같습니다.

 

 

익숙한 개념이 눈에 보이지 않으십니까?

바로 IWICImagingFactory 입니다. 네 그렇습니다~

WIC 도 바로 팩토리 형태로 생성이 됩니다.

 

추가된 변수들은 아래와 같은 절차에 의해 값이 채워집니다.

즉, 아래는 WIC의 처리 과정입니다.

 

  1. WIC 팩토리를 만든다.

  2. 파일 경로를 기반으로 해서 디코더를 만든다.

  3. 디코딩된 프레임을 가져온다.

  4. 변환기에 넣어서 Direct2D 형식으로 변환한다.

  5. Direct2D 비트맵을 생성하고, 이를 렌더링한다.

 

이제 위의 절차를 실제로 어떻게 처리하는지를 차근차근 살펴보겠습니다.

 

가장 먼저하는 초기화 작업입니다.

앞서 언급했듯이, WIC 도 팩토리 개념으로 생성됩니다.

COM 기반이기 때문에 API 인자들이 굉장히 어려워 보일 수도 있지만, 관심을 둘 부분은 아닙니다.

위와 같은 방법으로만 하면, WIC가 생성 되어진다는 개념으로만 인식하고 다음 단계로 넘어갑니다.

 

 

 

다음 단계는 디코더를 만들고, 이를 기반으로 해서 Direct2D 형식으로 데이터를 변환하는 것입니다.

이를 위해서 가장 먼저 해야 하는 일은

이미지를 읽어들이기 위한 디코더( Decoder )를 만드는 일입니다.


갑자기 등장한 생소한 용어에 조금 혼란스러울 것 같습니다.

우리가 사용하는 모든 멀티미디어 파일( 이미지, 영상, 사운드 등 )들은

굉장히 어려운 방법으로 압축이 되어있습니다.


이들에 대한 원리나 형식을 이해하는 것도 중요한 일일 수도 있지만,

이는 간단하게 본 페이지에서 설명할 수 있는 내용이 아닙니다.

물론 저도 이와 관련한 전문가는 더더욱 아닙니다.

우리는 단지 API만으로 이들에 대한 고민을 해결할 수 있습니다.

바로 그것이 WIC의 존재 이유 중 하나 일 것입니다.^^

 

즉, 우리는 이미 만들어진 API를 이용해서 손쉽게 이미지 파일을 읽어올 수 있습니다.

그런 역할을 하는 것이 바로 디코더입니다.

아래는 디코더를 가지고 실제 작업을 하는 부분입니다.

 

 

디코더는 WIC 팩토리 멤버함수로써 생성이 되어집니다.

우리가 사용했던 이 API의 원형은 다음과 같습니다.

<코드>

HRESULT CreateDecoderFromFilename(

[in] LPCWSTR wzFilename,

[in] const GUID *pguidVendor,

[in] DWORD dwDesiredAccess,

[in] WICDecodeOptions metadataOptions,

[out, retval] IWICBitmapDecoder **ppIDecoder

);

</코드>

 

이 API는 주어진 이미지 파일을 기반으로 해서 디코더를 생성해 줍니다.

첫 번째 인자로 파일명이 들어갑니다.

이 파일을 기반으로 해서 적합한 디코더를 생성해 주게 되는 것입니다.

예를 들어, PNG 파일이면 PNG에 대한 디코더가 필요하다고 인식하고,

그에 맞는 디코더를 자동적으로 생성해 주는 것입니다.

 

두 번째 인자는 선호하는 디코더 벤더(vendor)의 GUID를 입력해야 하는데, 지금은 NULL을 사용합니다.

 

세 번째 인자로는 디코더에 대한 접근 방법을 명시합니다.

읽기(read), 쓰기(write), 혹은 둘 다 가능한지를 넣어주면,

가장 최적화된 방법과 메모리 위치를 가지는 디코드를 생성해 줍니다.

위의 예제에서는 읽기용으로만 디코더를 만들었습니다.

 

네 번째 인자는 디코더의 캐시 관련 옵션입니다.

우리가 인자로 넘긴 WICDecodeMetadataCacheOnDemand는

필요한 이미지 정보만 캐시 하도록 옵션을 준 것입니다.

다음 번에 언급할 지도 모르지만, 하나의 이미지 파일에는 여러 이미지들을 포함하고 있을 수 있습니다.

예를 들면 GIF 애니메이션 이미지 같은 것들이다.

이런 경우에 유용하게 캐시하려면, 다른 옵션을 주어야 할 것입니다.

 

마지막 인자는 생성된 디코더를 저장할 디코더의 포인터입니다.

여기까지 작업하면, 우린 이제 파일을 읽은 디코더를 소유하게 되는 것입니다.

뭔가 절차 상으로 굉장히 복잡한 것처럼 느껴지죠?

 

 

다음으로 할 작업은 프레임(frame) 작업입니다.

프레임이라는 것은 실제 픽셀 데이터를 가지고 있는 비트맵입니다.

앞서 잠깐 언급했듯이, 하나의 이미지 파일은 여러 장의 이미지가 존재할 수 있습니다.

그런 경우를 대비해서 체크를 해야겠지만,

우린 여기서 단 하나의 프레임만이 존재한다고 가정할 것입니다.

디코더의 멤버 함수인 GetFrame()를 통해서 우린 가장 첫 번째 프레임을 얻을 수 있습니다.

이 프레임을 얻는다는 것은 우리가 화면에 표현할 수 있는 이미지를 얻었다는 것입니다.

 

이제 우리는 디코더를 통해서 이미지를 Direct2D에서 표현할 수 있도록

적절하게 변환을 해주어야
합니다.

CreateFormatConverter() API는 이를 위해서 컨버터를 만들어줍니다.

그리고 이 컨버터를 우리가 원하는 형태로 초기화를 시켜 줍니다.

컨버터의 멤버함수 Initialize() 는 이미지를 컨버팅 하면서

픽셀 정보를 보정해 줄 수 있는 많은 옵션을 가지고 있습니다.

이들 옵션에 대한 세부 설정을 하지 않았습니다.

그래서 위에 인자들 형태로 주면, 별다른 이미지의 수정 없이 32비트 포맷으로 남게 됩니다.

 

이제 마지막으로 실제 렌더링 가능한 형태의 메모리를 생성해야 합니다.

렌더타겟의 멤버함수인 CreateBitmapFromWicBitmap() API를 통해서 이 작업을 하게 됩니다.

여기까지 하면, 이미지를 렌더링 하기 위한 준비작업이 모두 끝난 것입니다.

 

저는 여기에 모든 옵션들을 나열하지 않습니다.

( 기본 목적인 이미지를 띄우는데 충실하고자 합니다.^^ )

 

 

생소한 API들이 눈에 많이 띄지만, 이들은 일련의 절차에 지나지 않습니다.

중요한 개념은 이미지를 읽어 들일 디코더를 만들고,

이 이미지 데이터를 Direct2D가 표현할 수 있는 픽셀 데이터로 변환하는 것입니다.

그리고 이 데이터를 렌더타겟에서 표현할 수 있는 비트맵으로 만들어서

렌더링 가능한 상태로 만듭니다.

위의 코드는 바로 이 개념들을 표현하고 있는 것입니다.

 

그러면 실제 WM_PAINT 메시지를 통해서 이들이 어떻게 화면에 그려야 하는지 살펴보겠습니다.

 

WM_PAINT 메시지에서는 렌더타겟이 존재하지 않는 경우, 렌더타겟을 생성합니다.

렌더 타겟이 존재한다면, 비트맵을 그리고 있습니다.

렌더타겟의 렌더링 작업도 BeginDraw() / EndDraw() 의 매커니즘 내부에서

특정 상태를 기반으로 작업을 수행하게 됩니다.

우리는 Clear() 라는 API를 통해서 렌더타겟의 메모리를 흰색으로 채우고 있습니다.

그리고 현재 우리가 이미지를 (0,0) 위치에 (300,300) 크기로 렌더링 합니다.

 

마법의 함수 DrawBitmap()

 

앞선 작업을 통해서 우린 Direct2D를 이용해서 이미지를 화면에 그릴 수 있었습니다.

만약 우리가 읽어 들인 이미지의 일부분만을 화면에 그리고 싶다면 어떻게 해야 할까요?

혹은 흐릿한 효과를 주고 싶다면 어떻게 해야 할까요?

굉장히 어려운 일들 같지만, 이들 기능은 DrawBitmap() 에 모두 옵션 인자로서 존재하고 있습니다.

( 무척 고마운 일이지요..^^ )

그렇기 때문에, 우리는 이 함수를 잘 사용할 수 있어야 합니다.

API의 원형은 다음과 같습니다.

 

<코드>

virtual void DrawBitmap(

[in] ID2D1Bitmap *bitmap,

[in, optional] const D2D1_RECT_F *destinationRectangle = NULL,

         FLOAT opacity = 1.0f,

D2D1_BITMAP_INTERPOLATION_MODE interpolationMode =

D2D1_BITMAP_INTERPOLATION_MODE_LINEAR

,

[in, optional] const D2D1_RECT_F *sourceRectangle = NULL

) = 0;

</코드>

 

첫 번째 인자는 우리가 렌더링 작업을 수행할 이미지입니다.

 

두 번째 인자부터는 옵션적으로 설정할 수 있다.

두 번째 인자는 렌더링 작업을 수행할 화면의 영역을 설정합니다.

NULL 로 설정한다면, 렌더타겟의 원점에 그리게 됩니다.

만약 이미지 크기보다 크게 설정된다면, 자동적으로 이미지를 확대해서 보여주게 됩니다.

 

세 번째 인자는 투명도를 설정합니다.

범위는 0.0~1.0 사이의 값으로 0.0은 투명한 상태를 나타내고 1.0은 불투명한 상태를 나타냅니다.

 

네 번째 인자는 우리가 렌더링하는 이미지가 회전을 하거나 크기가 조정되었을 때,

어떻게 부드럽게 보일 것인가에 대한 옵션을 설정하는 부분입니다.

즉, 보간( interpolation ) 옵션입니다.

 

마지막 인자는 원본 이미지에서 일정 영역을 보여주고 싶을 때 영역을 입력하는 옵션입니다.

이 때 단위는 해당 이미지 파일의 사이즈를 기준으로 영역을 설정해 주면 됩니다.

 

그러면, 간단하게 실제로 이미지의 일부 영역을 약간 투명하게 보여지는 것을 프로그램으로 구현해자면,

앞서 작성했던, 이미지 뷰어의 기능에서 DrawBitmap()만 변경해주면 됩니다.

 

<코드>

HRESULT hr = E_FAIL;

::g_ipRT->BeginDraw();

::g_ipRT->SetTransform( ::D2D1::Matrix3x2F::Identity() );

::g_ipRT->Clear( ::D2D1::ColorF( ::D2D1::ColorF::White ) );

                            

if( ::g_ipD2DBitmap != nullptr )

{

    ::D2D1_RECT_F dxArea = ::D2D1::RectF( 0.0f, 0.0f, 500.0f, 500.0f );

    ::D2D1_RECT_F dxSrc = D2D1::RectF( 0.0f, 0.0f, 250.0f, 250.0f );

    ::g_ipRT->DrawBitmap( ::g_ipD2DBitmap, dxArea, 0.3f,

D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, &dxSrc );

                

}

hr = ::g_ipRT->EndDraw();                

</코드>

 

우리는 간단하게 DrawBitmap() 의 인자들만 변경해주는 것만으로 이미지의 일부 영역만을 보여주고,

투명도를 조절할 수 있음을 확인해 보았습니다.

각각의 값을 변경시키면서, 여러가지 아이디어를 구상해 보기 바랍니다. ^^


아래 소스코드를 첨부합니다..


크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 상세한 설명 감사합니다 ^^)

  2. 김도균 2011/08/24 23:44

    지금 D2D1을 공부중입니다.
    혹시나 해서 질문을 올려보는데요.
    RanderTarge->DrawBitmap();//해주고
    RanderTarge->SetTransform();//을 해주면 비트맵이 변화가 되서 나옵니다. 그런데 이때 궁금 한점이 여러장의 비트맵을 생성했을 경우 DrawBitmap에는 각각의 비트맵을 선택해서 생성을 할수가 있는데 SetTransform은 일괄적으로 바껴버리네요 이걸 어떻게 해야하는건가요???

    • 어이쿠 이런 제가 확인이 늦었습니다.
      혹시 해결하지 못하셨다면,
      소스 코드를 보내주시면 제가 한번 체크해 드리겠습니다.^^

  3. 너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!

  4. 이디어가있는 모든 사람을 찾을 수 좋네요.

  5. 이것은 우리가 종종 회사의 메시지에 소프트 판매라고 부릅니다. 아마 당신은 새로운 제품의 범위를 제공, 확고한 가격이 있습니다, 사업의 시간 또는 단순히 회사의 메시지를 강화하려는가 퍼집니다.

  6. 인터넷 인터넷 비즈니스 세계의 기본 도구, 인터넷 자신의 비즈니스 및 고객 영향을 미치는 방법과 더 배워야 해 효과적인 사이트를 만드는 방법, 자신의 사업 계획에 그것을 통합하는 방법을 배우고 싶은 사람 당신은 충분한 시간과 관심이있다면.

  7. 나는이 프로그램을 사용하지 않은,하지만 난 나중에 내 프로젝트에 사용하려고합니다. 내 직원이 이해하고이 프로그램을 사용하여 빠르고 있었다 있도록 그 사용이 복잡하지 않습니다 바랍니다.

C++ AMP

Visual C++ 10 2011/06/28 09:00
Posted by 흥배

C++ AMP라는 것을 들어보셨나요?근래에 나온 단어입니다.

AMP AcceleratedMassive Parallelism의 약자로 병렬 프로그래밍과 관련된 것입니다.

 

C++ AMP 2주 전의 AMD Fusion 컨퍼런스에서MicrosoftHerb Sutter씨가(MS의프로그램 언어 아키텍터 이자 C++ 표준 위원 멤버) 처음으로공개한 것으로 다음 버전의 Visual Studio(현재는Visual C++)에서 GPGPU 프로그래밍환경을 제공하는 것을 뜻합니다.

 

병렬 프로그래밍에서 대해서 조금 깊게 공부하신 분들은 아마 GPGPU라는것을 들어본 적이 있으리라 생각합니다. GPGPU는 간단하게 말하자면 GPU CPU 처럼 사용하자라는 것으로 GPU의 높은 성능을 사용하여 CPU와 똑 같게는 사용할 수는 없지만연산 처리에서 높은 병렬 기능을 사용하여 CPU보다 훨씬 뛰어난 결과를 얻을 수 있습니다.

 

현재까지 GPGPU 개발환경은NVIDIA Cuda와 오픈 아키텍처인 OpenCL,DirectX 베이스의 DirectCompute가 있습니다.

 

GPGPU 프로그래밍의 단점은 프로그래밍이 복잡하고 아직 레퍼런스가적다는 단점이 있어서 아직은 일반적인 프로그래밍 영역에 들어오지 못하고 있습니다(사실 아직 일반 병렬프로그래밍도 쉽게 사용하지 못하고 있으니..). 그래서 GPGPU가나온 것은 몇 년이 지났지만 아직 일부 전문 영역에서만 사용되고 있었습니다.

 

그러나 CPU 아키텍처가 멀티코어에서 헤테로지니어스 아키텍처(이기종의 CPU가 결합.CPU+GPU)로 서서히 넘어가고 있어서 자연스럽게GPGPU 프로그래밍이 부각되고 있었습니다. 하지만 아직도 개발환경의 뒷받침이 부족한 상태였는데드디어 우리 개발자에게 친숙한 Visual C++에서 이런 문제를 해결하려고 합니다.

 

C++ AMP는 쉽게 말하면Visual C++에서 GPGPU 프로그래밍을 지원하는 것을 말합니다. Visual C++의 뛰어난 개발환경을 토대로 하여 이때까지 복잡했던GPGPU 프로그래밍을 일반 프로그래밍 하듯이 사용할 수 있게 해줍니다. 이로써 GPGPU가 일반 프로그래밍 영역으로 들어 올 수 있는 큰 계기가 되었다고 생각합니다.

 

 

C++ AMP에 대해서 AMD Fusion 컨퍼런스에서 데모를 시연한 Daniel Moth의 블로그에올라온 글을 정리하면

개발자의 생산성과 이식성을 저해하지 않고 헤테로지니어스 하드웨어 프로그래밍의 허들을 낮게 하여 프로그래밍 일반영역에서 사용할 수 있도록 한다.

 

현재의 대 규모 병렬 하드웨어(CPU GPU)의 사용을 돕기 위한 것만이 아닌 코드의 투자를 미래에 대비한 디자인으로 하여 견고하도록 한다.

 

Visual Studio의 일부분으로 또 다른 컴파일러나 다른 구문을배울 필요가 없다.

 

현재의 C++ 언어를 사용하며 C나다른 파생 언어가 아니다.

 

Visual Studio vNext와 완벽하게 통합하여 지원한다. 편집, 빌드, 디버그, 프로파일러 등 Visual Studio의 다른 모든 기능이 C++ AMP와 같이 동작한다.

 

기존의 Concurrency Runtime의 일부로 STL와 비슷한 형태의 라이브러리를 제공하여 amp.h 헤더 파일을제공한다.

 

병렬화를 주 특징으로 하여 헤테로지니어스 하드웨어 위에서 거대한 다 차원 데이터를 아주 쉽게 동작한다.

 

유일의 코어 C++ 언어 확장을 도입한다.

 

DirectX(DirectCompute) 위에 구축하지만 C++ AMP에서는 DirectX의 모습은 나타나지 않는다( DirectX를 몰라도 상관 없다).

 

 

 

또 동 세미나에서 기조 연설을 한 Herb Sutter씨의 강연 중 C++ AMP에 관한 내용으로는

C++ AMP에 의해서 기존의C++에서 큰 변경을 가하지 않으면서 언어를 확장하는 점을 강조하여 새로운 언어가 만들어서 개발자에게 혼란을 주는 것을 피했다라는것을 알림.

 

언어 확장으로 restrict() 함수와 array_view라는 2개의 type Key로 잡음. restrict()는 프로세서 아키텍처에 따라서 실행가능한 기능에 제한을 거는 것이고 array_view는 불 균인한 메모리 공간으로의 접근으로 생기는문제를 회피하기 위한 것으로 메모리 공간을 N 차원의 배열로서 작업하는 것을 뜻한다. 메모리 공간의 추상화라고 할 수도 있다. restrict()array_view는 프로세서 아키텍쳐와 메모리 공간의 차이를 흡수할 수 있는 것으로 C++ AMP의 중요한 Key이다.

 

C++ AMP의 컴파일러는Visual Studio의 차기 버전에서 들어갈 예정으로 릴리스는 이번 연말로 예상하고 있다. 또이 컴파일러는 오픈 사양일 예정으로 Windows 상의 VisualStudio 뿐만이 아닌 그 이외의 개발 환경(C++ Builder이나 이클립스 등)에서도 이용할 수 있도록 AMD와 협력 하여 개발 중이라고 한다.

 

 

 

 

 

DirectXDirectCompute를 사용한다고 하니 C++ AMP를 사용한 프로그램은 Windows Vista 이상에서만 사용할 수 있을 것 같습니다(이유는 DirectCompute DirectX 10에서 지원하기 때문).

 

GPGPU에 관심은 있었지만 아직 시기상조라고 생각하는 분들은 C++ AMP가 나오면 개발 허들이 크게 내려가므로 본격적으로 준비를 해도 좋을 것 같습니다. AMD에서는 헤테로지니어스 컴퓨팅 프로그래밍의 전망을 CUDA 등의독자 사양에서 OpenCL이나 DirectCompute 등의오픈 사양으로 이동하고, 전문 프로그래머만 프로그래밍 하는 시대를2011년까지로 보고 그 이후로는 일반 프로그래머가 완전하게 C++로 프로그래밍하는 헤테로지니어스컴퓨팅 프로그램이 올 것으로 보고 있다고 합니다.

 

저도 이제 슬슬 GPGPU 프로그래밍 쪽으로 들어가볼 예정인데 일단조만간 OpenCL부터 시작해 볼까 합니다. 연말에 VS vNext가 나올 수도 있다고 하니 그때 꼭 C++ AMP를 공부해서 그 내용을 공유하도록 하겠습니다^^

 

 

 

참고

헤테로지니어스 멀티 코어 http://jacking.tistory.com/513

 

Daniel Moth씨의 블로그 http://www.danielmoth.com/Blog/

  위 글을 정리한 한블로그(일본어)
 http://blogs.msdn.com/b/hiroyuk/archive/2011/06/20/10176783.aspx

 

AMD Fusion 컨퍼런스에서의 데모

비디오 http://channel9.msdn.com/posts/Daniel-Moth-Blazing-fast-code-using-GPUs-and-more-with-C-AMP

슬라이드 http://ecn.channel9.msdn.com/content/DanielMoth_CppAMP_Intro.pdf

 

일본의 임프레스 사이트에 올라온 Herb Sutter씨의 기존 강연정리 글

http://pc.watch.impress.co.jp/docs/news/event/20110617_453939.html

 

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 임준환 2011/11/17 10:17

    흥배님 좋은 정보 감사합니다!

  2. 서 실행가능한 기능에 제한을 거는 것이

Posted by 흥배

STL의 컨테이너를 사용해보았다면 forward_list라고 해서 딱히 어려운 부분은 없습니다. 다만 forward_list이 단 방향 리스트라는 것과 다른 컨테이너에서는 지원하는 기능이 일부 없다는 것을 잘 숙지해야 합니다.

 

필요한 헤더 파일

forward_list는 이름과 같은 ‘forward_list’라는 헤더 파일을 포함해야 합니다.

#include <forward_list>

 

 

[예제] forward_list를 사용하여 요소 추가, 순회, 삭제하기

#include "stdafx.h"

#include <iostream>

#include <forward_list>

 

using namespace std;

 

 

int main()

{

           forward_list< int > flist;

 

 

           cout << "flist에 추가한 요소들 출력" << endl;

           // 추가하기

           auto iter = flist.before_begin();

           for( int i = 0; i < 5; ++i )

           {

                     iter = flist.insert_after( iter, i );

           }

                    

           // 순회

           for( iter = flist.begin(); iter != flist.end(); ++iter )

           {

                     cout << *iter << endl;

           }

 

           cout << endl;

           cout << "flist의 요소들 중 일부를 삭제한 후 남은 요소들 출력" << endl;

           // 순회 하면서 일부 요소 삭제

           auto prev_iter = flist.before_begin();

           iter = flist.begin();

           while( iter != flist.end() )

           {

                     if( 3 == *iter )

                     {

                                iter = flist.erase_after( prev_iter );

                                continue;

                     }

                     ++prev_iter;

                     ++iter;

           }

 

           // 순회

           for( iter = flist.begin(); iter != flist.end(); ++iter )

           {

                     cout << *iter << endl;

           }

 

           return 0;

}

 

< 결과 >


 

위 예제를 보면 아시겠지만 forward_list std::list에 비해 성능 면의 이점을 가지고 있지만 사용 측면에서는 조금 불편한 점이 좀 있습니다. 그러나 C와 비슷한 성능을 내고 싶은 경우에는 좋은 선택 기가 될 수도 있습니다.

 


참고

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

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!


  2. 사람들이 정말 인상되는 색상을 사용하는 송장을 기억하고 읽을 수있는 정도 효과되지 않습니다 또 다른 방법입니다. 인보이스는 녹색 종이에 보냈습니다. 모두가 녹색 송장의 템포를 기억하기 때문에 우리가 통과 법안을 추구했을 때 실제로 얼음을 깰.

  3. 당신을 구입 아니라 이름에 투자하는 사람들에게 이점을 제공합니다. 그것은 저렴 방법, 개인 서비스의. 제공하는 서비스는, 심지어 가장 큰 대부분의 인터넷 기업을 통해 이점 것입니다.

Posted by 흥배

앞에까지는 STL의 알고리즘에 추가된 것들을 다루었는데 이번에는 컨테이너 하나를 소개하겠습니다. 사실 이 컨테이너는 저도 얼마 전까지만 하더라도 새로 추가 된지 몰랐습니다.^^;

 

새로 추가된 컨테이너의 이름은 forward_list입니다.

이름을 들어보니 대충 어떤 컨테이너인지 감이 오시죠?^^ 네 이 컨테이너는 기존의 list 컨테이너와 비슷한 종류의 컨테이너입니다.

 

 

forward_list를 만든 이유

표준 라이브러리(STL)에는 이미 리스트(std::list) 라이브러리가 있습니다. 이것은 쌍 방향 리스트입니다. list는 사용하기는 편하지만 사용 메모리나 처리 속도에 조금 아쉬운 점이 있습니다. 또 대 부분의 상황에서 쌍 방향 리스트가 필요한 경우보다는 단 방향 리스트만으로 충분한 경우가 자주 있습니다. 이런 이유로 C++0x에서는 단 방향 리스트를 추가하기로 했습니다.

 

 

forward_list의 설계 방침

1. 특별한 이유가 없다면 forward_list는 기존의 list의 설계에 맞춘다.

2. 설계 상의 선택 기가 여러 개인 경우 성능(속도와 사이즈)을 최우선 한다(C의 구조체로 구현하는 경우와 비교하여 Zero Overhead로 한다).

3. std::list insert eraseforward_list에서도 제공할 수 있지만 구현이 복잡해지고 성능 측면에서 좋지 않으므로 제공하지 않는다.

4. 다른 STL의 컨테이너들에 있는 size 함수를 제공하지 않는다. 이유는 요소 수를 보존하는 멤버를가지고 있으면 C언어에서 구현한 것과 비교해서 불필요한 메모리를 사용한다. 만약 이런 멤버를 가지고 있지 않으면서 size 함수를 지원하면 호출할 때마다 모든 요소를 세어야 하므로 계산량이 O(N)이 된다(그런데 유저는 다른 컨테이너와 같이 size의 계산량이 작을 것이라고 생각할 수 있다). 또 이미 unordered와 같은 연상 컨테이너도 기존의 요소를 만족하지 않고 있다.

 

 

STL list 컨테이너와 다른 점

forward_list는 기존의 list와 아래와 같은 점이 다릅니다.

1. forward_list는 단 방향 리스트(singly-linked-list)이다. 각 요소는 그 다음 요소를 가리키는 포인터를 하나만 가지고 있다(list은 양 방향 리스트).

2. (단 방향 리스트이므로) list에 비해서 메모리를 작게 사용한다. 이것은 각 요소의 메모리만이 아닌 컨테이너 그 자체의 사이즈도 작다. int 형에 대해서 list 12바이트라면 forward_list 8바이트이다(64비트에서는 각각 24, 16).

3. list에 비해 삽입/삭제 속도가 더 빠르지만 그 차이는 크지는 않다

4. 한 방향으로만 이동할 수 있다.

5. 삽입과 삭제는 지정한 요소의 다음 요소만 가능하다.

 

 

forward_list의 멤버 리스트

기능

멤버

대입

assign

반복자

befor_begin

 

cbefore_begin

 

begin

 

end

 

cbegin

 

cend

비었는지 조사

empty

현재 크기(size)

지원 안함

사이즈 변경

resize

모두 삭제

clear

선두에 추가

push_front

선두 요소 삭제

pop_front

선두 요소 참조

front

삽입

insert_after

삭제

erase_after

조건 삭제

remove

 

remove_if

중복 요소 삭제

unique

교환

swap

병합

merge

정렬

sort

반전

reverse

 

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 성능에 안 좋은 걸 아예 못 쓰게 만든 의미가 크군요 ㅋㅋ

  2. 너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!

  3. 긍정적인 사람들과 함께 생활을 입력하고 부정적인 모든 것을 버린다. 당신이 뭘하고 마음에 들지 않으면, 당신이 그것 시는지 사업 변경 계획을합니다. 당신이 뭘 사랑하면 그 결과는 엄청난 것입니다.

  4. 도메인 이름, 제목, 제품 이름, 기억하기 쉬운 것을 사용합니다. 많은 분야는 단어를 유인하기 위해 몇 가지 트릭을 사용합니다. 당신이 올바른 URL을 찾지 않는 그들은 항상 직접 액세스할 수 없습니다.

Posted by 흥배

C++03까지의 STL에는 데이터셋에서 가장 작은 요소를 찾을 때는 min_element, 가장 큰 요소를 찾을 때는 max_element를 사용하였습니다.

그런데 만약 최소와 최대를 동시에 찾을 때는 어쩔 수 없이 min_element max_element를 각각 호출해야 하는 불필요한 불편한 점이 있었습니다.

 

C++0x에서는 이런 불편함을 개선하기 위해 한번에 최소와 최고를 찾아주는 minmax_element 알고리즘이 새로 생겼습니다.

 

 

minmax_element

template<class ForwardIterator>

    pair< ForwardIterator, ForwardIterator >

        minmax_element( ForwardIterator _First, ForwardIterator _Last );

template<class ForwardIterator, class BinaryPredicate>

    pair< ForwardIterator, ForwardIterator >

        minmax_element( ForwardIterator _First, ForwardIterator _Last, BinaryPredicate _Comp );

 

minmax_element 알고리즘에는 조건자를 사용하는 버전과 조건자를 사용하지 않은 버전 두 가지가 있습니다. 데이터셋의 자료형이 유저 정의형(class struct를 사용한)이라면 조건자가 있는 버전을 사용합니다.

 

< 예제 코드 >

#include <iostream>

#include <algorithm>

using namespace std;

 

 

int main()

{

           int Numbers[10] = { 50, 25, 20, 7, 15, 7, 10, 2, 1, 3 };

          

           pair<int*, int*> MinMaxValue = minmax_element( &Numbers[0], &Numbers[10] );

 

           cout << "최소 값 : " << *MinMaxValue.first << endl;

           cout << "최대 값 : " << *MinMaxValue.second << endl;

          

           return 0;

}

 

< 결과 >


 

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!

  2. 사업은 문을 열고 고객이 오기를 기다리는 것입니다. 그들의 시간과 돈을 낭비 생각하기 때문에 그들은 광고하지 않습니다. 그들은 하루 통과로 환멸이 갈수록 나빠지고 시작하므로 고객은 노크 오지 않았다.

  3. 브랜드는 기업의 내부 및 외부 커뮤니케이 션을 나타내야합니다. 직원의 언어와 태도는 자선 브랜드와 목표를 거울 있는지 확인합니다.마크는 회사가 추진하고 모든 자료에 표시해야합니다.

Posted by 흥배

미국에서 개최된 TechEd 2011의 강연 중에서 VC++과 관련이 있는 ALM for C++ in Microsoft Visual Studio 2010이라는 세션을 소개하려고 합니다.

 

이 세션의 내용은 Visual Studio 2010(이하 VS)에서 C++에서 사용할 있는 ALM 기능을 소개하고, VS의 차기 버전(이하 vNext) 구현될 ALM 기능을 소개하고 있습니다.

사실 저는 이 세션에 대해서 별로 기대하지 않았습니다. 그러나 세션 내용을 보니 저의 생각을 완전히 뛰어 넘었습니다. VS의 차기 버전을 많이 기대하게 되었습니다.^^
이 세션의 내용 중 vNext에 관련된 내용을 정리해 보았습니다.

 

이 세션의 내용을 짧게 정리하면 기존 VS에서 닷넷만 되고 C++은 안 되는 기능을 이제는 C++에도 동등하게 지원한다’ 입니다.

저는 Visual Studio.NET 2002에서부터 VS에 대한 불만 중 하나가 닷넷 프로그래머나 C++ 프로그래머나 똑 같은 돈을 주고 VS를 구입하는데 왜 tool의 많은 기능 중 닷넷만 되고 C++은 안 되냐라는 것이었는데 이제 이런 불만이 사라질 것 같습니다.

 

그럼 ‘ALM for C++ in Microsoft Visual Studio 2010’ 세션을 간단하게 소개하겠습니다.

( 본문에 사용한 그림은 VC++ 팀 블로그에 올라온 그림을 사용하였습니다 )

 

현재 C++에서 VS ALM을 모두 사용하고 있는 사람은 3할정도

 

Visual Studio 2010에서의 ALM 기능

Premium 버전

- ALM과 관련된 기능으로 Code Coverage, Static Analysis, Profiling, Concurrency Profiling을 지원.

Ultimate 버전

- Load Testing, Lab Menagement 지원

- TFS에서는 Version Control, Team Build 지원

 

 

vNext에서의 변화

2010에서 지원하던 Architecture tools의 기능을 강화하면서 새로운 기능을 추가

Native ALM에 투자를 하여 기존의 많은 ALM 기능을 Native에 대응해 나갈 것임

 

 

코드 분석


VS2010에서도 사용할 수 있는 기능으로 vNext에서 더욱 개선
상세한 정보를 전달하기 위해서 UI를 다시 디자인
분석 엔진 개선으로 더욱 강력하게 에러나 경고를 진단
제안을 클릭하면 코드 위에 하이라이트 하여 문제점을 가시화

 

 

Architecture Tools  (VS2010에서 지원)

    Dependency diagram by binary

Native 애플리케이션의 아키텍처를 동적으로 시각화하여 의존 관계를 빠르게 파악할 수 있음

이름 공간, 타입, 함수 단위로 자유자재로 의존 관계를 시각화

 

     Dependency diagram by include files

헤더 파일의 의존 관계도 그래프화(이 기능 사용하면 빌드 시간 단축을 위해 헤더 파일 정리할 때 정말 좋을 것 같습니다).
헤더 파일에 색을 붙여서 구분이 쉬워짐. 또 이미지 파일로 저장도 가능

 

   Create a layer diagram and run validation

기존 VS 프로젝트를 드래그&드랍으로 레이어 그림으로 변환. 아키텍처 검증과 의존 관계 생성도 할 수 있음.


 아키텍처 검증은 TFS의 자동 빌드로 실행

 


그리고 드디어 vNext ALM for C++의 끝판왕 소개입니다.

.......

...........

..............

무려 C++ Unit Test Framework 지원(뭐 사실 2010에서 닷넷은 이미 지원하고 있죠^^;;).

저는 이 기능은 정말 의외였습니다. 제가 tool에서 가장 지원해주기 바라는 기능이 드디어 들어오네요. 이 세션에서도 이 C++ Unit Test Framework 소개할 때 청중들의 박수갈채가 뿜어져 나왔다고 합니다. 아마 저도 이 세션을 들었으면 기립박수를 했을 것 같네요^^

이제 우리 C++ 프로그래머들도 이제 순정(?) Unit Test Framework을 사용할 수 있어 따로 설치하지 않아도 되고 녹색 버튼과 빨간 버튼을 볼 수 있습니다.

화면 멋지지 않나요저는 지금 회사에서 구글의 C++ Unit Test Framework를 사용하고 있는데 UI면에서는 비교를 할 수 없을 정도로 좋네요^^


단위 테스트 프로젝트 템플릿이 있고, CppUnitTest.h, TEST_CLASS, TEST_METHOD 매크로가 있다고 합니다.

위 그림의 왼쪽이 Unit Test Explorer인데 테스트에 속성을 붙일 수 있는데 이 속성은 TEST_OWNER(), TEST_PRIORITY(), TEST_IGNORE() 등이 있습니다.

 

Code Coverage

 

Unit Test Explorer에서 아이콘 클릭으로 코드 커버리지 데이터 리포트를 볼 수 있습니다.

바이너리 단위, 함수 단위로도 가능합니다. 원래 이 기능은 2010에는 있었지만 닷넷만 가능했죠. 이제 이것을 C++에서도 사용할 수 있습니다.

소스 코드의 하이라이트로 커버리지 상황을 시각화 할 수도 있습니다.

 

 

 

앞서 이야기 했듯이 기존에 닷넷만 지원하는 기능을 앞으로는 C++도 사용할 수 있습니다. 그리고 당연하게 vNext에서 새로 만들어지는 기능도 이젠 차별 없이 C++도 지원한다고 합니다.

vNext에서는 VS tool 기능을 반쪽만 아닌 닷넷과 같이 모두 사용할 수 있을 것 같아서 너무 좋네요^^

 

기억을 더듬어 보면 2008이 나오기 전 2007년 겨울에 MS 본사의 VC++ PM이 왔어 앞으로 VC++의 기능이 혁신적으로 개선 될 것이라고 했을 때 일종의 립 서비스라고 생각했고, 2008이 나왔을 때 역시나(물론 이전보다는 좀 좋아졌지만) 라고 생각했습니다. 그러나 2010이 나오면서 인텔리센스를 새로 만든 것을 보고 립 서비스가 아니었구나 라고 생각하게 되었고 이번 세션을 통해서 MS VC++에 대한 확고한 의지를 볼 수 있었습니다.

 

vNext가 정확하게 언제 나올지는 모르겠지만 VC++ C++0x 기능과 C++ for ALM 기능으로 기대가 정말 많이 되고 나오면 공부할 것이 많을 것 같습니다.

 

‘ALM for C++ in Microsoft Visual Studio 2010’ 세션에 대한 정보는 VC++ 팀 블로그의 글이나 Channel 9에서 영상으로 볼 수 있습니다.

 

 

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 좋은 글 잘 읽었습니다. 다음버전 기대되네요 :)

  2. 좋은 정보 감사합니다. Vnext가 차기 버전이라 하셨는데,
    언제쯤 보게 될지??? 아님 이미 나와있나요??
    ㅎㅎ
    알려주세요

Posted by 흥배

데이터셋을 시퀸스(연속적인)한 값으로 채우고 싶을 때는 iota 알고리즘을 사용합니다.

앞서 소개한 알고리즘들은 <algorithm> 헤더 파일에 정의 되어 있는 것에 반해 iota 알고리즘은 <numeric> 헤더 파일에 정의 되어 있습니다.

 

itoa

template<class ForwardIterator, class T>

  void iota(ForwardIterator first, ForwardIterator last, T value);

 

 

아래는 예제 코드와 결과 입니다.

#include <iostream>

#include <vector>

#include <numeric>

using namespace std;

 

int main()

{

           vector<int> Numberlist;

           Numberlist.push_back( 2 );

           Numberlist.push_back( 5 );

           Numberlist.push_back( 7 );

           iota( Numberlist.begin(), Numberlist.end(), 2 );

 

           for( auto IterPos = Numberlist.begin(); IterPos != Numberlist.end(); ++IterPos )

           {

                     cout << *IterPos << endl;

           }

 

           return 0;

}

 

< 결과 >

 

위 예제를 보면 아시겠지만 iota의 세 번째 인자의 값이 시작 값이고, 이후에 값이 하나씩 증가합니다.

 

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!

Posted by 흥배

is_heap is_heap_until는 앞서 소개했던 is_sorted, is_sorted_until과 비슷한 알고리즘입니다. 차이가 있다면 is_heap is_heap_until는 정렬이 아닌 Heap을 다룬다는 것만 다릅니다.

 

is_heap은 데이터셋이 Heap으로 되어 있는지 아닌지, is_heap_until는 데이터셋에서 Heap이 아닌 요소의 첫 번째 위치를 반환합니다.

 

is_heap

template<class RandomAccessIterator>

    bool is_heap(

        RandomAccessIterator _First,

        RandomAccessIterator _Last

    );

template<class RandomAccessIterator, class BinaryPredicate>

    bool is_heap(

        RandomAccessIterator _First,

        RandomAccessIterator _Last,

        BinaryPredicate _Comp

    ); 

 

 

is_heap_until

template<class RandomAccessIterator>

    bool is_heap_until(

        RandomAccessIterator _First,

        RandomAccessIterator _Last

);

template<class RandomAccessIterator, class BinaryPredicate>

    bool is_heap_until(

        RandomAccessIterator _First,

        RandomAccessIterator _Last,

        BinaryPredicate _Comp

);

 

 

is_heap is_heap_until는 각각 조건자를 사용하는 버전과 사용하지 않는 버전 두 개가 있습니다. 조건자를 사용하지 않는 경우는 operator< 를 사용합니다.

 

 

그럼 is_heap is_heap_until을 사용한 아주 간단한 예제 코드를 봐 주세요^^

#include <iostream>

#include <algorithm>

using namespace std;

 

 

int main()

{

           int Numbers1[10] = { 50, 25, 20, 7, 15, 7, 10, 2, 1, 3 };

           int Numbers2[10] = { 50, 25, 20, 7, 15, 7, 10, 6, 11, 3 };

           int Numbers3[10] = { 50, 25, 20, 7, 15, 16, 12, 3, 6, 11 };

          

          

           bool IsResult = false;

           IsResult = is_heap( &Numbers1[0], &Numbers1[10], [](int x, int y) { return x < y; } );

           cout << "Numbers1 Heap인가 ? " << IsResult << endl;

 

           IsResult = is_heap( &Numbers2[0], &Numbers2[10], [](int x, int y) { return x < y; } );

           cout << "Numbers2 Heap인가 ? " << IsResult << endl;

 

           IsResult = is_heap( &Numbers3[0], &Numbers3[10] );

           cout << "Numbers3 Heap인가 ? " << IsResult << endl;

 

           cout << endl;

           int* NumIter = is_heap_until( &Numbers2[0], &Numbers2[10], [](int x, int y) { return x < y; } );

           cout << "Numbers2에서 Heap되지 않은 첫 번째 위치의 값 : " << *NumIter << endl;

 

           return 0;

}

 

< 결과 >

 

 

 

ps : 자료구조 Heap에 대해서 잘 모르시는 분들은 아래의 글을 참고해 주세요

http://blog.naver.com/ctpoyou/105423523


저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 죽은 indited 컨텐츠 자료, 엔트로피 주셔서 감사합니다. "당신은 믿음을 거의 할 수 있지만, 당신은 그것없이는 아무것도 할 수 없다." 새뮤얼 버틀러에 의해.

  2. 보드 사업 조각하기 전에 주위를 이동하고 보드를 끌어하려고 시도하는 등 사업을 알 수 있습니다. 사무실, 상점 또는 귀하의 비즈니스에 더 많은 보드가 잠재 고객을 유치할 수 있도록하는 방법을 결정하기 위해 경쟁 업체의 공장을 방문하십시오.

  3. 좋은 브랜드는 스폰서 능력과 조직의 전문성의 깨끗한 이미지를 강조 제출하여야한다. 개발과 브랜드 가치를 홍보하는 것은 덜 알려진 자선 단체와 함께 중소 기업의 손해에, 네 편이 고객을 유치할 수 있습니다.

Posted by 흥배

is_sorted는 데이터셋이(컨테이너나 배열) 정렬되어 있다면 true를 반환하고, 그렇지 않다면 false를 반환 합니다.

is_sorted_until는 데이터셋에서 정렬되어 있지 않는 요소의 첫 번째 위치를 반환합니다.

 

is_sortedis_sorted_until의 원형은 아래와 같습니다.

is_sorted

template<class ForwardIterator>

    bool is_sorted( ForwardIterator _First, ForwardIterator _Last );


template<class ForwardIterator, class BinaryPredicate>

    bool is_sorted( ForwardIterator _First, ForwardIterator _Last, BinaryPredicate _Comp );

 

 

is_sorted_until

template<class ForwardIterator>

    ForwardIterator is_sorted_until( ForwardIterator _First, ForwardIterator _Last);

 

template<class ForwardIterator, class BinaryPredicate>

    ForwardIterator is_sorted_until( ForwardIterator _First, ForwardIterator _Last,

               BinaryPredicate _Comp );

 

위의 is_sortedis_sorted_until의 원형을 보시면 알겠지만 조건자(함수객체)를 사용하는 버전과 사용하지 않는 버전 두 가지가 있습니다.

조건자를 사용하지 않는 경우 기본으로 operator<가 적용됩니다.

 

프로그래머는 코드로 이해하죠? ^^ 그럼 바로 예제 코드 들어갑니다.

이번 예제는 간단하게 만들기 위해 정수 배열을 사용해 보았습니다. 아마 STL을 이제 막 공부하고 있는 분들은 알고리즘을 STL의 컨테이너에만 사용할 수 있는 것으로 알고 있는 분들도 있을텐데 그렇지 않습니다. 아래 예제는 int 형 배열을 사용하였습니다.

 

< 예제 코드 >

#include <iostream>

#include <algorithm>

using namespace std;

 

 

int main()

{

           int Numbers1[5] = { 1, 2, 3, 4, 5 };

           int Numbers2[5] = { 5, 4, 3, 2, 1 };

           int Numbers3[5] = { 1, 2, 4, 3, 5 };

           bool IsResult = false;

 

          

           IsResult = is_sorted( &Numbers1[0], &Numbers1[5], [](int x, int y) { return x < y; } );

           cout << "Numbers1. 오름 차순 ? " << IsResult << endl;

 

           IsResult = is_sorted( &Numbers2[0], &Numbers2[5], [](int x, int y) { return x > y; } );

           cout << "Numbers2. 내림 차순 ? " << IsResult << endl;

 

           IsResult = is_sorted( &Numbers3[0], &Numbers3[5], [](int x, int y) { return x < y; } );

           cout << "Numbers3. 오름 차순 ? " << IsResult << endl;

 

           cout << endl;

           cout << "is_sorted에서 조건자(함수객체)를 생략한 경우 " << IsResult << endl;

           IsResult = is_sorted( &Numbers1[0], &Numbers1[5] );

           cout << "Numbers1 is_sorted의 결과는 ? " << IsResult << endl;

           IsResult = is_sorted( &Numbers2[0], &Numbers2[5] );

           cout << "Numbers2 is_sorted의 결과는 ? " << IsResult << endl;

 

           cout << endl;

           int Numbers4[8] = { 1, 2, 3, 5, 4, 5, 7, 8 };

           int* NumIter = is_sorted_until( &Numbers4[0], &Numbers4[5], [](int x, int y) { return x < y; } );

           cout << "Numbers4에서 정렬되지 않은 첫 번째 위치의 값 : " << *NumIter << endl;

 

           return 0;

}

 

< 결과 >


 

 

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 정보 주셔서 감사합니다.

  2. 너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!

  3. 이 규정을 준수하지만, 귀하의 비즈니스에 허용위원회 만들 수 있습니다. 귀하의 비즈니스와 IT가 열려 시간을 설명 너무 사람이 많아, 몇 가지 단어를 사용하지 마십시오. 눈에 띄는 색상을 만들고 맞춤법이나 문법을 발생하지 세부 사항을 확인하십시오.

  4. 결정하기 위해 마케팅 조사의 정보를 사용하여, 예를 들어, 시장 점유율, 효율성 촉진 정책, 귀하의 제품과 서비스에 반응.

Posted by 흥배

제가 http://vsts2010.tistory.com/category/C++/CLI 에 올린 글을 정리한 것으로 보기 편하도록 정리하여 pdf 파일로 만들었습니다.

이후 관련 글을 포스팅 하면 일정 시간이 지난 후 다시 이 글에도 추가하여 배포할 예정입니다.





저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 좋은 자료 감사합니다. ^^

  2. 감사합니다. 흥배님 덕분에 많이 배웠습니다.

  3. 너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!

  4. 새로운 아이디어와 혁신에 마음을 여십시오. 자신의 단어 겁쟁이 말하는 찾아내는 경우에, 기회는 열려 딱딱한 아니라입니다. 아이디어는 돈이 많은 친구 또는 직원이 당신이 그들의 아이디어를 받아들이려고하지 않는 생각을 염두에두고 있습니다 인쇄할 수 있습니다.

  5. 마케팅 조사는 매출과 이익에 영향을 미치지 시장 동향의 식별을 포함합니다. 마케팅 조사는 일반적인 지식보다 훨씬 더 많은 정보를 제공합니다.

  6. C++/CLI가 필요해서 보기만 하다가 감사하다는 말은 해야할거 같아서 글을 썼어요...