[bluez] sdp와 android
socket을 잘 설정하고 uuid도 맞고 서버 측 코드에서 서비스 등록도 잘 해도 device로부터 getUuids()를 줘도 반영이 안 되고, 안드로이드 측에서 connect()만 실행하면
java.io.IOException: read failed, socket might closed or timeout, read ret: -1
위와 같은 exception 나면서 연결이 안 되는 경우가 있는데 양측 기기에서 전부 페어링 해제를 하자
그 다음 서버를 실행하고(물론 sdp가 등록 되도록 해야 함) 페어링을 해주자.
이제 fetchUuidsWithSdp()를 실행하고 getUuids() 결과 값을 받아보면 추가되어있는 것을 볼 수 있다.
연결도 잘 될 것이다.
'공부 > C/C++' 카테고리의 다른 글
[rpi3/qt] Win10 Pro 64bit -> Raspbian Stretch 크로스빌드 환경 구축 (0) | 2019.05.01 |
---|---|
[번역/SDL2] 이벤트 기반 프로그래밍 (0) | 2015.12.12 |
SDL2 vc140용 개발용 라이브러리 x64 (SDL2 development library compiled on vc140 x64) (0) | 2015.12.12 |
[번역/SDL2] Getting an Image on the Screen (0) | 2015.12.12 |
[llvm/clang] clang을 윈도우에서 써보자 (0) | 2015.11.22 |
[rpi3/qt] Win10 Pro 64bit -> Raspbian Stretch 크로스빌드 환경 구축
다음 참조: http://wapel.de/?p=603
위에 나온 deps 모두 깔고 다음 명령어 실행
sudo apt-get install libc6-armhf-cross libc6-dev-armhf-cross
sudo ln -s /lib/arm-linux-gnueabihf/libpthead-2.14.so /usr/lib/arm-linux-gnueabihf/libpthread.so.0
sudo rm -rf /usr/lib/chromium-browser/libs
여기 에서 raspberry-gcc6.3.0-r4.exe를 설치하고 TOOLS/UpdateSysroot.bat를 실행한다.
다음 경로를 붙여넣는다.
/lib
/usr/include
/usr/lib
/usr/local/include
/usr/local/lib
/opt
이제 하단 체크박스를 클릭하고 sync 한다.
./configure -release -opengl es2 -device linux-rasp-pi3-g++ -platform win32-g++ -device-option CROSS_COMPILE="/c/SysGCC/raspberry/bin/arm-linux-gnueabihf-" -sysroot /c/SysGCC/raspberry/arm-linux-gnueabihf/sysroot -opensource -confirm-license -make libs -prefix /usr/local/qt5pi -extprefix /root/qt5pi -hostprefix /root/qt5 -no-use-gold-linker -v -no-gbm -nomake examples -nomake tests -qt-freetype -qt-harfbuzz -skip qtscript -no-xcb
2019.05.04 deps 수정
'공부 > C/C++' 카테고리의 다른 글
[bluez] sdp와 android (0) | 2020.05.06 |
---|---|
[번역/SDL2] 이벤트 기반 프로그래밍 (0) | 2015.12.12 |
SDL2 vc140용 개발용 라이브러리 x64 (SDL2 development library compiled on vc140 x64) (0) | 2015.12.12 |
[번역/SDL2] Getting an Image on the Screen (0) | 2015.12.12 |
[llvm/clang] clang을 윈도우에서 써보자 (0) | 2015.11.22 |
[번역/SDL2] 이벤트 기반 프로그래밍
때론 게임에선 이미지를 띄울 때 사용자로 부터 입력 값을 받아야 할 때가 있습니다. SDL의 이벤트 핸들링 시스템을 이용하면 이런 것도 가능합니다.
//Main loop flag
bool quit = false;
//Event handler
SDL_Event e;
코드는 SDL이 초기화 되고, (이전 튜토리얼에서 쓰인) 미디어가 불러와진 다음, 사용자가 종료 했는지에 대한 여부를 추적하고 종료 플래그를 선언합니다. 우리는 이 부분부터 응용 프로그램을 시작했기 때문에, 확실하게 false로 초기화 되었습니다.
또한 SDL_Event 공용체를 선언해야 합니다. SDL 이벤트는 키를 누르거나, 마우스의 움직임, 게임패드의 동작 혹은 그 외 등등, 같은 것들입니다. 이번엔 프로그램을 종료시키는 종료 이벤트를 배워 봅시다.
//While application is running
while( !quit )
{
이전 튜토리얼에서, 우리는 프로그램을 닫으려면 몇 초 동안 기다려야 했었습니다. 이번엔 사용자가 끄기 전까지 만든 프로그램은 대기하도록 해보겠습니다.
사용자가 종료를 원하지 않는 상태라면 우리는 프로그램을 계속 루프해야 합니다. 프로그램이 활성화 되어있는 동안 계속 실행되는 루프를 메인 루프, 가끔은 게임 루프라고 불립니다. 이건 어떤 게임이든 핵심적인 요소지요.
//Handle events on queue
while( SDL_PollEvent( &e ) != 0 )
{
//User requests quit
if( e.type == SDL_QUIT )
{
quit = true;
}
}
메인 루프의 상단에는 이벤트 루프가 있습니다. 이건 전부 빌 때까지 이벤트 큐를 계속 처리합니다.
여러분이 키를 누르거나, 마우스를 이동하거나, 터치스크린을 터치한다면, 이벤트 큐에 이벤트를 넣어줍니다.
이벤트 큐는 이벤트를 순서대로 저장하고 이를 처리하기 위한 대기 시간이 발생합니다. 무슨 이벤트가 발생했는지 알고싶을 때, SDL_PollEvent를 호출하여 가장 최근에 발생한 이벤트를 얻어 폴링합니다. SDL_PollEvent는 이벤트 큐에서 가장 최근의 이벤트를 가지고 있으며 이벤트를 SDL_Event에 넣고 함수로 전달합니다.
SDL_PollEvent는 큐가 빌 때까지 계속 반복됩니다. 큐가 비어있다면, SDL_PollEvent는 0을 반환합니다. 그래서 결국 이 코드 쪼가리는 이벤트 큐가 빌 때까지 이벤트를 계속 폴링해줍니다. 만약 이벤트 큐에 SDL_QUIT 이벤트가 있다면(which is the event when the user Xs out the window), 우리가 응용 프로그램을 종료 할 수 있도록 true로 플래그를 설정하고 프로그램을 종료합니다. 1
//Apply the image
SDL_BlitSurface( gXOut, NULL, gScreenSurface, NULL );
//Update the surface
SDL_UpdateWindowSurface( gWindow );
}
프레임에 대한 이벤트 처리를 완료한 다음, 화면에 그리며 (이전 강좌에서 이야기했던 것과 같이) 업데이트 합니다. 종료 플래그가 true로 설정되어있는 경우, 응용 프로그램은 루프가 끝나면 종료됩니다. false로 되어있다면 윈도우의 x 버튼을 누르기 전까지 계속 동작합니다.
- 능력 부족으로 인한 번역 불가 [본문으로]
'공부 > C/C++' 카테고리의 다른 글
[bluez] sdp와 android (0) | 2020.05.06 |
---|---|
[rpi3/qt] Win10 Pro 64bit -> Raspbian Stretch 크로스빌드 환경 구축 (0) | 2019.05.01 |
SDL2 vc140용 개발용 라이브러리 x64 (SDL2 development library compiled on vc140 x64) (0) | 2015.12.12 |
[번역/SDL2] Getting an Image on the Screen (0) | 2015.12.12 |
[llvm/clang] clang을 윈도우에서 써보자 (0) | 2015.11.22 |
SDL2 vc140용 개발용 라이브러리 x64 (SDL2 development library compiled on vc140 x64)
https://www.libsdl.org/ 에서 공식적으로 빌드한 버전을 받을 수 있습니다.
-
2015 버전에선 빌드가 안 돼서 꽤 고생 좀 했다.
자동적으로 빌드 배포해주는 곳에선 64비트 버전은 안 담아주고 ㅠㅠ
직접 빌드하려는데 vs가 헤더 경로를 정말 징그럽게 인식 못 해서(...) 꽤 오래 붙잡고 있었다.
빌드 환경:
SDL2-2.0.3
Visual Studio 2015 Community
Release x64
미테스트
x86은 이미 https://buildbot.libsdl.org/sdl-builds/sdl-visualstudio/ 에서 배포 중이며,
헤더 파일도 여기서 받으시면 됩니다.
zlib 라이센스를 따라 배포합니다.
'공부 > C/C++' 카테고리의 다른 글
[rpi3/qt] Win10 Pro 64bit -> Raspbian Stretch 크로스빌드 환경 구축 (0) | 2019.05.01 |
---|---|
[번역/SDL2] 이벤트 기반 프로그래밍 (0) | 2015.12.12 |
[번역/SDL2] Getting an Image on the Screen (0) | 2015.12.12 |
[llvm/clang] clang을 윈도우에서 써보자 (0) | 2015.11.22 |
[C++ STL] vector(벡터) erase 함수 제대로 사용하기 (0) | 2015.10.22 |
[번역/SDL2] Getting an Image on the Screen
이미 창이 열려있겠죠. 그럼 이제 이미지를 넣어봅시다.
메모: 이 튜토리얼에서는 소스 코드의 주요 부분만을 다룰 겁니다. 전체 프로그램의 경우, 전체 소스 코드를 다운로드해야 합니다.
// SDL을 시작하고 창을 만듭니다
bool init();
// 미디어를 부릅니다
bool loadMedia();
// 미디어를 비우고 SDL을 닫습니다
void close();
우린 처음 튜토리얼에선 모든 정의를 main 함수에 넣었었죠. 작은 프로그램이었던지라 가능했던 겁니다만, 진짜 프로그램(비디오 게임 등등) 같은 곳에선 코드를 모듈화 할 수 있어야 합니다. 이는 스스로 쓴 코드를 조그마하게 잘라, 디버그를 쉽게하고, 재사용 가능토록 해줄 겁니다.
// 창이 렌더링 될 겁니다
SDL_Window* gWindow = NULL;
// 창 내부 표면
SDL_Surface* gScreenSurface = NULL;
// 이미지를 로드하고 화면에 띄우기
SDL_Surface* gHelloWorld = NULL;
여기에서 우리는 몇 가지 글로벌 변수를 선언합니다. 일반적으로 큰 프로그램에선 전역 변수를 사용하면 매우 복잡해지기 때문에 쓰지 않도록 해야하지만, 소스 코드를 가능한 한 단순하도록 쓰기 원하기 때문에 이렇게 쓰도록 합니다. 이 프로그램은 하나의 소스 파일만 쓰기 때문에 그 문제는 걱정하지 않아도 됩니다.
일단 SDL 표면(Surface)라는 새로운 데이터 타입이 보입니다. SDL 표면을 렌더링 하는데 필요한 모든 데이터와 함께 이미지의 픽셀을 포함한 단순한 화상 데이터입니다. SDL 표면을 렌더링하기 위해 CPU를 사용합니다. 물론 하드웨어 이미지 렌더링도 할 수 있지만 조금 더 어렵습니다. 그러니 우리는 쉬운 방법을 먼저 배우기로 하죠. 나중에 읽을 튜토리얼에서는 GPU 가속 이미지를 렌더링 하는 방법을 다루도록 하겠습니다.
여기선 파일을 로드해 화면에서 이미지(윈도우 내부 참조)를 다룰 겁니다.
이러한 SDL 표면에 포인터가 있다는 걸 볼 수 있습니다. 그 이유는 1) 우리는 동적 이미지를 로드하기 위해 메모리를 할당하기 위함입니다. 그리고 2) 메모리 위치에 따라 이미지를 참조하는 것이 좋습니다. 슈퍼 마리오 브라더스 같은 반복되는 이미지로 같은 벽돌이 렌더링 되는 걸 생각해보세요. 한 번 렌더링 할 때마다 새로운 이미지를 만드는 것보다 한 번 만든 이미지의 복사본을 가지고 계속 렌더링 해주는 게 훨씬 효과적이겠지요.
추가로, 포인터는 항상 초기화 해야 합니다. 우리는 포인터를 선언 할 때, 즉시 NULL로 선언했습니다.
bool init() {
// 플래그 초기화
bool success = true;
// SDL 초기화
if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
printf( "SDL이 초기화 되지 않음! SDL_Error: %s\n", SDL_GetError() );
success = false;
} else {
// 창 생성
gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
if( gWindow == NULL ) {
printf( "창이 생성되지 않음! SDL_Error: %s\n", SDL_GetError() );
success = false;
} else {
// 윈도우 표면 구하기
gScreenSurface = SDL_GetWindowSurface( gWindow );
}
}
return success;
}
여기선 SDL 초기화와 윈도우 생성 코드를 쓰고 고유한 기능을 집어넣은 것을 볼 수 있습니다. SDL_GetWindowSurface를 부르는 것도 새로운 점입니다.
이미지를 윈도우 내부에 보여주기 위해 윈도우 내부와 윈도우 내부에 들어갈 이미지를 얻을 필요가 있습니다. 그래서 윈도우 내부의 표면을 잡아 SDL_GetWindowSurface를 호출하는 거죠.
bool loadMedia() {
// 성공 플래그 로드
bool success = true;
// 스플래시 이미지 로드
gHelloWorld = SDL_LoadBMP( "02_getting_an_image_on_the_screen/hello_world.bmp" );
if( gHelloWorld == NULL ) {
printf( "이미지를 로드할 수 없습니다 %s! SDL Error: %s\n", "02_getting_an_image_on_the_screen/hello_world.bmp", SDL_GetError() );
success = false;
}
return success;
}
미디어 로드 함수를 부르면, SDL_LoadBMP를 사용하여 지정한 이미지가 로드됩니다. SDL_LoadBMP는 BMP 파일의 경로를 취해 표면에 반환 시킵니다. 함수가 NULL을 반환하는 경우, 콘솔 창에서 SDL_GetError를 사용하여 오류를 표시해 실패했다고 알려줍니다.
주목해야 할 중요한 점은 위 코드는 현재 작업 디렉토리 아래 경로의 "02_getting_an_image_on_the_screen" 폴더 내부에 존재하는 "hello_world.bmp"라는 이미지라고 가정해두었다. 응용 프로그램이 실행되는 위치로부터 상대 경로가 됩니다. 1
// 표면 업데이트
SDL_UpdateWindowSurface( gWindow );
SDL_UpdateWindowSurface를 사용하여 이 프레임에 대해 표시할 것을 모두 그린 후 화면을 업데이트 해줘야 합니다. 화면에 그려진 것을 볼 때, 우리가 평소에 보듯 화면에 바로 그려지는 것은 아닙니다. 기본적으로 대부분의 렌더링 시스템은 두 개의 버퍼가 존재하는데, 각 버퍼를 프론트 버퍼와 백 버퍼라고 부릅니다.
SDL_BlitSurface 같은 그리기를 호출할 때, 백 버퍼가 렌더링하고 프론트 버퍼가 화면에 표시하게 됩니다. 그 이유는 대부분의 프레임이 화면에 많은 것들을 그려야 하기 때문입니다. 만약 프론트 버퍼만 존재한다면, 프레임이 그대로 그려지게 되고 결국 미완성 프레임을 보게 된다는 겁니다. 그러니 먼저 모든 것을 백 버퍼에 담아, 다시 프론트 버퍼에게 넘겨주면 이제 사용자가 완성된 프레임을 보게 되는 거죠.
물론 이는 각 프레임이 뿌려지고 난 뒤 SDL_UpdateWindowSurface를 모든 프레임마다 호출해주지 않는다는 의미입니다.
// 2초 기다리기
SDL_Delay( 2000 );
}
}
// 자원을 비우고 SDL을 종료
close();
return 0;
}
그럼 이제 모든 것이 창에 렌더링 되었고, 창이 갑자기 사라지는 것을 막기 위해 2초 동안 대기 시간을 주었습니다. 2초간 기다리면, 프로그램이 닫히겠지요.
- 위 튜토리얼의 리소스, 소스코드는 여기서 받으세요.
- 원래 좀 더 긴 내용인데 C++ 기능과는 불필요한 설명이라 간추렸다. [본문으로]
'공부 > C/C++' 카테고리의 다른 글
[번역/SDL2] 이벤트 기반 프로그래밍 (0) | 2015.12.12 |
---|---|
SDL2 vc140용 개발용 라이브러리 x64 (SDL2 development library compiled on vc140 x64) (0) | 2015.12.12 |
[llvm/clang] clang을 윈도우에서 써보자 (0) | 2015.11.22 |
[C++ STL] vector(벡터) erase 함수 제대로 사용하기 (0) | 2015.10.22 |
c++ 블럭 주석을 OnOff 하기 편하게 사용하기 (0) | 2015.02.17 |
[llvm/clang] clang을 윈도우에서 써보자
! 기존 llvm 공식 가이드에서는 svn으로 소스를 받으라는데, 필자는 svn 같은 건 써본적이 한 번도 없어서 git으로 대체함.
! 공식 llvm은 git을 제공하지 않는 것 같지만, 다행히 github에 llvm을 미러링 하고있는 저장소가 있기 때문에 해당 저장소를 사용.
시작 전 필요한 것
git, cmake, python, visual studio 2013↑, getgnuwin32(optional)
필자는 2015 커뮤니티 버전으로 진행함. 파이썬 버전 호환성은 모르겠으나 2.7.10으로 진행
일단 cmd를 열어 llvm을 받을 폴더로 이동한다. 일단 위치를 C:\로 가정하겠다.
cd C:\
C:\ >
기술적으론 clang을 사용하기 위해선 llvm이 필요하다. 어째서 필요한지는 여기선 기술하지 않겠다. 그럼 이제 git에서 llvm을 받자.
C:\ > git clone https://github.com/llvm-mirror/llvm
Cloning into 'llvm'...
...
완료 되면 llvm\tools로 들어가 git에서 clang을 받는다.
C:\ > cd llvm\tools
C:\llvm\tools > git clone https://github.com/llvm-mirror/clang
Cloning into 'clang'...
...
그럼 이제 llvm 상위 폴더로 돌아가 프로젝트를 빌드할 폴더를 만들어 해당 폴더로 진입한다.
C:\llvm\tools > cd ..\..
C:\ > mkdir build
C:\ > cd build
C:\build >
이제 cmake로 llvm을 컴파일 한다. 컴파일 하면서 clang도 같이 컴파일 된다.
C:\build > cmake -G "Visual Studio 14 Win64" ..\llvm
...
컴파일러 종류(Generator)에 대한 플래그는 cmake --help 쳐보면 Generator 항목 아래에 나온다. 그 뒤에 아키텍쳐를 붙여 컴파일 한다.
컴파일이 완료되면 build 폴더에 LLVM.sln 파일을 Visual Studio로 열고, ALL_BUILD를 오른쪽 마우스 버튼으로 눌러 빌드하면 된다.
그 이후 ..\build\빌드 플래그\bin에 들어가보면 clang.exe가 있다.
이제 해당 bin 폴더를 path에 등록하면 윈도우에서도 clang으로 컴파일 할 수 있다.
'공부 > C/C++' 카테고리의 다른 글
SDL2 vc140용 개발용 라이브러리 x64 (SDL2 development library compiled on vc140 x64) (0) | 2015.12.12 |
---|---|
[번역/SDL2] Getting an Image on the Screen (0) | 2015.12.12 |
[C++ STL] vector(벡터) erase 함수 제대로 사용하기 (0) | 2015.10.22 |
c++ 블럭 주석을 OnOff 하기 편하게 사용하기 (0) | 2015.02.17 |
포인터와 동적배열 (0) | 2014.08.21 |
[C++ STL] vector(벡터) erase 함수 제대로 사용하기
CCL에 따라 복제한 게시글입니다.
원본, 저작권자 : http://createcode.tistory.com/13
1 2 3 4 5 6 | for (std::vector<_Object>::iterator iter = m_vecP.begin(); iter != m_vecP.end(); ){ if ((*iter).rank == rank) iter = m_vecP.erase(iter); else ++iter; } |
'공부 > C/C++' 카테고리의 다른 글
[번역/SDL2] Getting an Image on the Screen (0) | 2015.12.12 |
---|---|
[llvm/clang] clang을 윈도우에서 써보자 (0) | 2015.11.22 |
c++ 블럭 주석을 OnOff 하기 편하게 사용하기 (0) | 2015.02.17 |
포인터와 동적배열 (0) | 2014.08.21 |
(C++) 클래스 내의 static 지정자 (0) | 2014.08.07 |
c++ 블럭 주석을 OnOff 하기 편하게 사용하기
- 본 게시물은 CCL을 따라서 복제한 게시물입니다.
C++ 프로그램을 짜다보면 주석을 걸었다가 풀었다가 해야할 일들이 많습니다.
그때 보통 /* */ 주석을 썼다가 지웠다가 하거나
Visual Studio 의 기능을 사용해서 영역을 지정해서 주석처리를 했다가 지우는 방식을 사용합니다.
이렇게 사용하는 것도 편리하긴 하지만 색다른 방식이 있습니다.
Lua에서 사용하는 방식인데 C++에서도 사용이 되더라구요.
주석을 칠때 아래와 같은 방식으로 주석을 사용하면 주석을 풀었다 걸었다 하기 굉장히 편리 합니다.
/*
// 뭔가 코드가 잔뜩 있을 거라고 상상하세요.
//*/
기본적인 사용법은 동일한데 뭔가 끝나는 부분이 오묘합니다.
주석 끝부분이 주석처리 되어 있습니다.
뭔가 아!!! 하는 느낌이 드시는 분들이 계실지 모르겠습니다.
원리는 간단합니다.
위쪽 주석에다가 / 표시 하나만 추가하면 //* 형태가 되면서 /* 라인이 주석처리가 됩니다.
그러면 아래쪽에 */ 가 남게 되면서 문법 오류를 내는데요.
//*/ 로 적어두면서 해당 라인이 주석으로 인식되어 문법 오류가 나지 않습니다.
//*
// 이렇게 하면 주석이 풀립니다.
//*/
/*
// 이렇게 하면 주석이 됩니다.
//*/
시험삼아 한번 사용해 보시면 재미있습니다. 저는 종종 이용해요 ㅋ
Lua 에서도 영역을 주석처리할 때
--[[
이 영역이 주석이 됩니다.
--]]
위와 같은 방식으로 주석을 이용합니다. 그런데
---[[
이 영역의 주석이 풀립니다.
--]]
-기호 하나만 추가함으로서 영역의 주석을 풀어줄 수 있습니다.
하나의 언어를 벗어나 다른 언어의 패러다임을 배운다는 것이 이런 장점이 있네요.
[출처] c++ /* */ 주석을 OnOff 하기 편하게 사용하기|작성자 구(milennium9)
'공부 > C/C++' 카테고리의 다른 글
[llvm/clang] clang을 윈도우에서 써보자 (0) | 2015.11.22 |
---|---|
[C++ STL] vector(벡터) erase 함수 제대로 사용하기 (0) | 2015.10.22 |
포인터와 동적배열 (0) | 2014.08.21 |
(C++) 클래스 내의 static 지정자 (0) | 2014.08.07 |
(C++) 컨테이너【set】 (0) | 2014.04.04 |
pdf 파일.
원본 : http://www.parkjonghyuk.net/lecture/2011-2nd-lecture/programming2/chap10.pdf
백업본 : http://nitori.in/X9D2/chap10.pdf
'공부 > C/C++' 카테고리의 다른 글
[C++ STL] vector(벡터) erase 함수 제대로 사용하기 (0) | 2015.10.22 |
---|---|
c++ 블럭 주석을 OnOff 하기 편하게 사용하기 (0) | 2015.02.17 |
(C++) 클래스 내의 static 지정자 (0) | 2014.08.07 |
(C++) 컨테이너【set】 (0) | 2014.04.04 |
(C++) 컨테이너【map】 (0) | 2014.04.04 |
(C++) 클래스 내의 static 지정자
출저 : 프로그래밍 입문 사이트 ~bituse~ | http://bituse.info/cp/17
이번엔 클래스 안에서 static 지정자를 사용했을 때의 경우에 대해서 설명합니다. 클래스 내부에서 static을 사용하면, 변수는 정적 멤버 변수가 되고, 그 클래스의 인스턴스를 몇 개를 만들어도, 그 변수는 전부 공유되어 하나가 됩니다.
일반적으로 클래스 내부의 변수는, 인스턴스 마다 변수를 가지고 있지만, static 지정자를 단 변수에 대해서는, 하나 뿐이 되어 공유되게 됩니다. 일반적인 인스턴스를 만들면, 그 클래스의 변수를 포함하는 영역이 확보되지만 1, 이 정적 멤버 변수른 인스턴스를 만들지 않아도 처음부터 공간이 확보되어 있습니다.
즉, 클래스의 구성원이 있더라도, 영역만은 다른 곳에서 확보되어있다는 것입니다. 그러므로, 클래스 외부의 글로벌 영역에서 변수를 선언하고 실체를 작성해야 합니다.
또한 함수에 static 지정자를 쓰면 정적 멤버 함수가 되며, 인스턴스를 만들지 않아도 그 기능을 수행할 수 있습니다. 하지만, 그 함수에서 접근하는 변수는 정적 멤버 변수 뿐입니다. 또한 클래스의 일반 함수는 정적 멤버 변수, 멤버 함수에 액세스할 수 있습니다.
아래코드를 보세요:
class TEST { public: int temp; static int figure;
static void func(int a) { figure = a; //temp 변수는 정적 멤버가 아니기 때문에 액세스 불가능 //temp = a; } }; int TEST::figure = 10; int main(void) { //인스턴스가 생성되어도 액세스 가능 printf("%d\n",TEST::figure); //정적 함수 인스턴스 생성 없이 액세스 가능 TEST::func(100); printf("%d\n",TEST::figure); //TEST 클래스를 세 번 선언 TEST aaa[3]; aaa[0].temp = 1; aaa[1].temp = 2; aaa[2].temp = 3; aaa[0].figure = 10; aaa[1].figure = 11; aaa[2].figure = 12; //각각 표시 for (int i=0; i<3; ++i) { printf("%d,",aaa[i].temp); } //개행 puts(""); for (int i=0; i<3; ++i) { printf("%d,",aaa[i].figure); } //개행 puts(""); return 0; }
위 코드를 실행하면 이렇게 나옵니다.
변수 figure와 func 함수에 static 지정자를 달고 있습니다 그리고 글로벌 영역에서 figure를 선언하고 실체를 만들고 있습니다. main 함수 내부를 보십쇼. 처음에 printf를 실행하고 있습니다만, 아직 인스턴스는 만들지 않았음에도 불구하고 정적 멤버 변수 figure의 값을 표시할 수 있습니다. 또한 정적 멤버 함수 func에도 액세스 할 수 있습니다.
정적 멤버에는 이렇게
클래스_이름::정적_멤버_변수(함수)
로 액세스 가능합니다.
다음은 TEST 클래스의 인스턴스를 세 개 생성합니다. 일반 변수 temp에는 각각의 인스턴스에서 다른 값을 넣어줍니다. 마찬가지로 변수 figure에도 각각의 인스턴스에서 다른 값을 넣어줍니다. 하지만 각각의 값을 표시하여 보면, 일반 temp 변수는 서로 다른 값이 들어있는 반면, 정적 멤버 변수 figure는 모두 12로 되어있습니다.
aaa[0].figure = 10;
aaa[1].figure = 11;
aaa[2].figure = 12;
이 코드에서, 각각의 인스턴스에 다른 숫자를 넣었습니다만, 정적 멤버 변수이므로, 변수가 공유되고, 어떤 인스턴스에 대해서도 마지막으로 할당한 12의 값이 표시되었다는 겁니다.
이것이 정적 멤버 변수와 정적 멤버 함수의 구조입니다. 이해하실 수 있으셨습니까?
- 인스턴스를 선언하면 프로세스가 끝날 때까지 메모리를 상주하는 것 [본문으로]
'공부 > C/C++' 카테고리의 다른 글
c++ 블럭 주석을 OnOff 하기 편하게 사용하기 (0) | 2015.02.17 |
---|---|
포인터와 동적배열 (0) | 2014.08.21 |
(C++) 컨테이너【set】 (0) | 2014.04.04 |
(C++) 컨테이너【map】 (0) | 2014.04.04 |
(C++) 컨테이너【queue】 (0) | 2014.04.04 |