Thursday, January 14, 2010

[C++] C++ RTTI (Run Time Type Information)

http://furyheimdall.tistory.com/156

[C++] C++ RTTI (Run Time Type Information)

Posted on 2008/06/17 20:01
Filed Under Computer languages

  • 이 글은 Jake에 의해 www.jakeworld.net 에서 작성되었습니다.

  • 퍼가실 때는 이 박스와 함께 복사해주세요.



RTTI 란?

Run Time Type Information or Run Time Type Identification의 약자로 실행시간에 타입정보를 식별 정도로 풀이할 수 있습니다.

정확한 의미는, 실행중에 기반 클래스 타입 포인터의 실체를 밝혀내는데 목적을 두고 있습니다.


C++ 표준화의 역사와 RTTI의 등장

1991: First meeting of WG21

1994: CD1 : CD2에 내용이 없어서 CD1으로 판단하였는데 정확하지 않습니다>

1996: CD2

1997: FDIS (Final Draft International Standard)

1998: C++ Standard (C++98)


CD : Committee Draft

TR : Technical Report

WG : Working Group

WG21 : WG for C++


RTTI 는 현재 표준화 된 지원을 제공하지만, 애초부터 표준이었던 것은 아닙니다.

C와의 후방 호환성을 유지하며, C의 효율성 유지에 대한 우려때문이었습니다.

가상함수라는 대안도 있었지만 결국 정적 타입체크 와 가상함수들로는 불가능한 문제점들이 제시되었습니다.

결국 C++ 표준화 위원회는 RTTI 추가를 승인하였습니다.

그 이전에는 각각 독자적으로 RTTI 기능을 소스코드 수준에서 구현하여 제공하였는데, 그 대표적인 예가 92년에 등장한 MFC의 RTTI 입니다.

CRuntimeClass 와 몇가지 매크로를 통해서 구현하게 되어있는데 현재까지도 MFC에서 사용되고 있습니다.

MFC RTTI 에 관해서는 http://captainthomas.tistory.com/entry/MFC-RTTI-CRuntimClass 를 참고하시기 바랍니다.


RTTI 는 어째서 필요한가?

RTTI는 위에서 언급했듯 실행중에 기반 클래스 타입 포인터의 실체를 밝혀내는데 목적으로 하고 있습니다.

정확하게 다형성을 가진 객체에 대해 정확한 타입을 알아내기 위해서 나왔다고 볼 수 있습니다.


간단한 예를 들면 Base 클래스가 있고 그것을 상속받은 Child1, Child2 클래스가 존재한다고 가정했을때,

Base* m_Base = new Child1();

이렇게 할당하였을 경우 기존의 방법으로는 실행중에 m_Base 가 가르키고 있는 객체가 Child1 이라는 것을 알 수가 없습니다.

하지만 RTTI 를 사용하면 Child1 타입이라는 것을 정확하게 알 수 있게 됩니다.


이것은 하나의 단편적인 예이며 사실 가상함수를 사용하는 다형성을 통해서 굳이 런타임때 타입을 알필요가 없을지도 모릅니다.

하지만 가상함수로도 해결할 수 없는 문제점을 RTTI 를 통해서 해결 가능한 부분들이 존재합니다.

이에 관해서는 http://blog.naver.com/moodern?Redirect=Log&logNo=80005025903 를 참고하시기 바랍니다.


제약사항

위에서 다형성이란 말을 언급하였는데 , 이 다형성을 구현하기 위해서 C++ 은 가상함수를 사용하며, 이 가상함수를 위해 별도의 공간을 사용하고 있습니다. 바로 vftbl 이라는 가상함수 테이블입니다.

RTTI 정보는 vftbl 에 저장되기 때문에 가상함수가 사용된 클래스에 한해서만 정보가 유지되게 됩니다.

즉, 비다형성 클래스의 객체는 RTTI 정보를 가지지 않습니다. (프리미티브 타입들도 마찬가지입니다)

이는 RTTI를 일반적인 클래스 객체에 두게되면 C와의 하위호환성을 포기해야 되는 사태가 발생합니다.

C의 구조체와 C++의 클래스 객체는 바이너리 호환성을 지니기 때문에 C에서 객체에 액세스가 가능한데 , C++ 클래스가 멤버중 vitrual 을 가지게 되면 액세스가 불가능한 점을 볼 수가 있습니다.


RTTI 의 간단한 예

다형성과 비다형성을 가진 클래스에 대해 RTTI 정보에 대해서 쉽게 테스트 해 볼 수 있습니다.

01#include
02#include
03
04class Base
05{
06public:
07 void B(){}
08};
09
10class Child1 : public Base
11{
12public:
13 void C(){}
14};
15
16class Child2 : public Base
17{
18public:
19 void C(){}
20};
21
22void main()
23{
24 Base* Cast = new Child1();
25 Base* Cast2 = new Child2();
26 printf( "%s \n", typeid(*Cast).name() );
27 printf( "%s \n", typeid(*Cast2).name() );
28}


위와 같이 비 다형성 클래스에 대해서 선언하여 클래스 타입을 조회하면 둘다 "Class Base"로 나오게 됩니다.

정체성을 잃어버리고 자기가 누군질 모르고 있습니다.

즉 RTTI 정보를 가지지 않게 됩니다.


01#include
02#include
03
04
05class Base
06{
07public:
08 void B(){}
09 virtual void a(){}
10};
11
12class Child1 : public Base
13{
14public:
15 void C(){}
16 virtual void a(){}
17};
18
19class Child2 : public Base
20{
21public:
22 void C(){}
23 virtual void a(){}
24};
25
26void main()
27{
28 Base* Cast = new Child1();
29 Base* Cast2 = new Child2();
30 printf( "%s \n", typeid(*Cast).name() );
31 printf( "%s \n", typeid(*Cast2).name() );
32
33}


이번에는 클래스 내부에 의미없는 virtual 멤버를 포함시켰습니다.

수행결과는

"Class Child1"

"Class Child2"

로 나오게 됩니다. 지가 누군지 알게 되었네요.

RTTI 정보를 가지게 되는 것을 알 수 있습니다.


C++ RTTI 에 의존하는 dynamic_cast 도 상속 관계 안에서 하나 이상의 가상함수를 가지고 있어야 하며, RTTI 기능이 활성화 되어야 사용할 수 있는 제약사항을 동일하게 가집니다.


마치며

간단하게 C++ RTTI 에 알아보기 위해서 썼기 때문에 정작 중요한 예나 비용등의 언급은 빠졌습니다.

RTTI 에 관련된 정보는 많이 있기 때문에 검색을 통해 충분히 찾을 수 있을 것으로 생각됩니다.

자세한 예와 사용에 대해서는 http://blog.naver.com/lovinghc?Redirect=Log&logNo=30013832987 를 참고하시기 바랍니다.

C++. template 템플릿. 자유로운 자료형 만들기 P

back:http://sosal.tistory.com/52

시작하자마자 소스를 펼쳤어요.
간단한 소스를 4개 볼것입니다.
이 소스들만 분석하면 템플릿이 어떤건지
정확하게 이해가 될거같네요!! ㅎㅎ

여튼 탬플릿을 사용하는 목적은
자유로운 변수를 만들기 위함입니다.
어떠한 자료형이 들어오던 간에
전부다 알아서 처리해줍니다.

#include
using namespace std;

template //print라는 함수인데 위에 이상한게 있네요.
void print(a data){ //함수 인자는 위에 템플릿 옆 class a. a라는 변수가 들어간다는 말인데.. 흠..
cout<<"print함수가 받아온 값은 "<} //결국 클레스로 정의된 a라는 변수의 형태로 data를 출력합니다.

int main(){


print (10); // int형으로 넘겨줌
print (10); // 그냥 숫자 대입? 역시 int형
print ("korea"); // 문자열 대입? 출력이 되네요
print (3.12312); //double형인가요? 출력됩니다.
return 0;
}

template의 신비는 이렇게 시작합니다.
template 함수위에 템플릿으로 선언해주고 아래에 함수를 선언합니다.
void func(a data1,a data2, b data3.......> 템플릿으로 정의해준 데이타 (사실 내용이란건 없지만..)를 자료형으로
이용하여 함수안에 인자로 사용하게 됩니다.
이때 들어오는 인자값은 내용이 전혀 없는 class로 정의된 변수입니다.
어떠한 변수가 들어오면 자동으로 그 변수를 인식하게 되어
특정한 자료형에 갇히지 않고, 어떠한 변수든 자유롭게 사용할 수 있는 함수를 만들 수 있게 됩니다.
그럼 좀더 나아간 소스를 봅니다.

=======================================================================================================

#include
using namespace std;

template //자료형은 템플릿으로 a형 하나를 만들었네요
void print(a data, a data2){ //위와 동일한 print 함수를 만들었는데, 변수를 2개 만들었습니다.
cout<<"print함수가 받아온 값은 "< cout<<"print함수가 받아온 값은 "<}

int main(){
print (10,32); //앞의 는 class a라는 변수를 int형이라고 바꾸는 것입니다.
print (10,52); //이렇게 수를 넣으면 일반적으로 int로 들어가게 됩니다.
print (3.12312,3.24132); //첫번째 인자가 double 형이므로, class a는 double 형태로 바뀌게 되고
//두번째 인자 역시 double형으로 받을 수 있는 형태의 자료이기 때문에 가능합니다.
/* *****print (152,52.2231); */ // -> int형과 double을 함께쓰면 error
print (10,3.14); //이것은 10과 3이 출력됩니다. class a가 int형으로 인식되었기 떄문입니다.
print (10,3.14); //이것은 10과 3.14로 출력됩니다. class a가 double형으로 인식되었기 떄문입니다.
return 0;
}

위 주석처리된 print(152,52.2231)을 제외한 결과값입니다.



주석처리 된 부분을 error가 났다고 말했는데, 왜 에러인가?를 보면
처음에 들어온 자료형은 int 형이어서 템플릿은 내부적으로 class a를 int로 바꿉니다.
그다음에 들어오는 변수는 보니까 double형이네요?
이렇게 되면 int형으로 받아야할지 double형으로 받아야 할지
시스템이 고민을 하게 됩니다.
이렇게 고민을 하게 되는 상황에서는 에러가 납니다.

만약 첫번째 인자가 int형인 3이었고, 두번째가 문자열 bb 였다면
어떤걸 선택해야할까요?
그래서 이 방법을 해결하기 위해서는
함수를 호출할때 ex)print (52,22.11) 이런식으로
print 함수가 받는 자료형을 임의로 바꿔주던지,
아니면 template를 선언할때 처음부터 자료형을 따로 주는 방법이 있습니다.

template //자료형은 템플릿으로 a형 하나를 만들었네요
void print(a data1, b data2){
}
이렇게 되면 a data1과 b data2에 어떠한 다른 값을 넣더라도
서로 다른 변수로 인식하기 때문에
자유로운 변수 사용이 가능하겠죠??

=======================================================================================================

세번째 소스입니다.


#include
using namespace std;

template
void print(a data, b data2){
cout<<"print함수가 받아온 값은 "< cout<<"print함수가 받아온 값은 "< cout<<"c="<}

int main(){
print (10,3.14);
return 0;
}

c는 전해줄 방법이 없었는데,
print 함수에서 인자값으로 c를 넘기는게 아니라
이런 방식으로 넘길 수 있다는걸 기억하세요.

=======================================================================================================

그럼 마지막 소스를 보겠습니다.

#include
using namespace std;

template


void func(a data1,b data2,c data3){
cout<<"data1 ::"< cout<<"data2 ::"< cout<<"data3 ::"<}

int main(){
func (3.32,52,52.323);
return 0;
}

마지막 소스는 1,2,3번 소스를 본다면 당연히 이해가 가셔야합니다.
그럼 template으로 아무 프로그램이나 한번 짜보세요~ ㅎㅎ

저작자 표시 비영리 변경 금지
Posted

Tuesday, January 12, 2010

netstat 명령어

http://kcdl.tistory.com/entry/포트-오픈-여부-확인하는-방법


확인 프로그램

Eclipse 에서 SSH 사용하기

2008/07/17 14:23

이클립스에서 작업하고 SecureCRT 나 SSH Secure Shell 를 사용해서
업로드 또는 콘솔작업을 했었는데요..

불편하더라구요...(나만그런가ㅋㅋ...)
늘 작업하면서 이클립스에서 몽땅 해결할수 있는 방법이 없을까 ..
그래서 개발시간을 좀더 줄여서 일찍퇴근하고 커피한잔 더 마실수는 없는걸까..
하고 생각을 했습니다.

그래서 찾아보니..바로 답이 나오네요..^^;;(역쉬촌놈입니다.)
사용해보니..아직까진 편하다는 느낌은 안들구....
좀더 사용해봐야 할듯합니다.


설치법
Eclipse 3.3 에서 설치하였습니다.

Help > Software Updates > Find and Install 가서

Search for new features to install 실행

New Remote Site 클릭해서 name 은 아무거나 입력하고 URL 에는 http://eclipse.jcraft.com

OK 클릭

추가한 다음 체크박스에 체크하고 Finish 하면 업데이트를 받을수가 있습니다.



사용하기
설치했다면
Window > Show View > Other 클릭하면 SSH2 라는 폴더가 생겼습니다.
선택해서 Tab은 원하는 위치에 추가시킵니다.
아래 이미지를 클릭하면 이미지처럼 설치가 될거구요. Open Shell ..클릭해서
원하는 서버로 접속하시면 됩니다.

접속방법..

사용자@IP:포트
root@111.222.333.444:222

입니다.

사용자 삽입 이미지



이거와 관련하여 좀더 자세히 알고 싶으시면 아래 링크로 이동 바랍니다.

http://www.jcraft.com/eclipse-sftp/index.html

Monday, December 28, 2009

컴퓨터 용량단위

비트-바이트-킬로바이트-메가바이트-기가바이트-테라바이트-페타바이트-엑사바이트-제타바이트-요타바이트

BIT-BITE-KB-MB-GB-TB-PB-XB-ZB-YB

순입니다.

8비트가 1킬로바이트가 됩니다. 즉 8 비트 = 1KB

나머지는 1024KB=1MB 그 다음이 1024MB=1GB

순입니다. 말하자면 비트 에서 바이트로 갈 때는 8로 넘어가고 나머지는 다 1024로 들어갑니다.

Byte (바이트)

KB(킬로바이트) 1,024 = 210 Byte

MB(메가바이트) 1,048,576 = 220Byte

GB(기가바이트) 1,073,741,824 = 230 Byte

TB(테라바이트) 1,099,511,627,776 = 240 Byte

PB(페타바이트) 1,125,899,906,842,624 = 250 Byte

EB(엑사바이트) 1,152,921,504,606,846,976 = 260 Byte

ZB(제타바이트)1,180,591,620,717,411,303,424 = 270Byte

YB(요타바이트)1,208,925,819,614,629,174,706,176 = 280 Byte

이렇게 입니다.

참고로 현재 하드디스크 용량은 2TB로 나왔습니다.

Sunday, December 27, 2009

linux find

  1. 현재 디렉토리( . ) 이하에 확장자가 .html( -name "*.html" ) 인 파일만 ( -type -f )
    • find . -name "*.html" -type f -ls
  2. 파일 크기
    • 파일 크기가 300KB 이상( -size +300k )인 파일만 (호스팅되는 홈피내에 큰 사이트의 파일이 있는지 찾을 때 유용)
      find . -size +300k -ls
    • 파일 크기가 500bytes 이하( -size -500c )인 파일만
      find . -size -500c -ls
  3. 수정일
    • 수정한지 20일 이상( -mtime +20 )된 파일과 디렉토리
      find . -mtime +20 -ls
    • 수정한지 20일 이상된 파일만
      find . -mtime +20 -type f -ls
    • 수정한지 20일 이상된 파일만 삭제 ( -exec rm {} \; ) (정기적으로 20일이 지난 파일을 삭제할 때 유용)
      find . -mtime +20 -type f -ls -exec rm {} \;
    • 수정한지 3일 이내( -mtime -3 )의 파일만 (백업할 때 유용)
      find . -mtime -3 -type f -ls
    • 수정한지 30분 이내( -mmin -30 )의 파일만
      find . -mmin -30 -type f -ls
  4. 퍼미션 및 파일 소유
    • 파일시스템 전체( / )에서 SUID/SGID가 설정된 모든 파일 목록을 얻음
      find / -type f \( -perm -04000 -o -perm -02000 \) -ls
    • 소유자가 없는 파일 목록을 얻음 (사용자는 이미 삭제했는데, 파일이 남은 경우)
      find / -nouser -o -nogroup
  5. 출력 형식 지정
    • 출력 형식을 printf로 만들어서 (출력 결과를 다른 프로그램에서 받아서 쓸 때 유용)
      %h = 경로, %f = 파일명, %k = KB, %s = Bytes
    • 형식 : <경로/파일명> <파일크기KB>
      find . -printf "%h/%f \t %kKB \n"
      ... 생략 ...
      ./public_html/phps/icon/type/pcx.gif 4KB
      ./public_html/phps/icon/type/ra.gif 4KB
      ./public_html/phps/icon/type/sound.gif 4KB
      ./public_html/phps/icon/type/text.gif 4KB
    • 형식 : <경로/파일명> <파일크기Bytes>
      find . -printf "%h/%f \t %sKB \n"
      ... 생략 ...
      ./public_html/phps/icon/type/movie.gif 912Bytes
      ./public_html/phps/icon/type/mp3.gif 958Bytes
      ./public_html/phps/icon/type/pcx.gif 897Bytes
      ./public_html/phps/icon/type/ra.gif 903Bytes
      ./public_html/phps/icon/type/sound.gif 932Bytes
  6. 홈페이지 포팅할 때 퍼미션 안 맞는 경우 유용한 것
    • 확장자가 .htm* .gif, .js, .css 인 것만 퍼미션을 644(rw-r--r--)로
      find . -name "*.htm*" -o -name "*.gif" -o -name "*.js" -o -name "*.css" -exec chmod 644 {} \;
    • 파일은 퍼미션을 644로
      find . -type f -exec chmod 644 {} \;
    • 디렉토리는 퍼미션을 701로
      find . -type d -exec chmod 701 {} \;
    • 하위의 모든 퍼미션을 바꾸지 않고 depth를 지정하여 제한을 둘 때
      옵션 : -maxdepth 숫자 (1=현재디렉토리만, 2=현재디렉토리 포함하여 한단계 하위디렉토리까지만)
      find . -maxdepth 1 -type d -exec chmod 701 {} \;
      ※ -maxdepth는 -type나 -perm 등의 조건연산자가 아닌 옵션이다. 따라서 조건연산자보다 먼저 사용해야한다. (다른 명령처럼 옵션을 먼저쓰는 것으로 이해하면 됨)
      find . -type -d -maxdepth 1 과 같이 사용하는 것은 옳지 않다.