Sunmoon_BIT/C++ programing 2010. 4. 15. 22:59


RTTI 란?

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

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


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

1991: First meeting of WG21

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

1996: CD2  <Exception Handling, Template 등장>

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 정보에 대해서 쉽게 테스트 해 볼 수 있습니다.

  1. #include <stdio.h>  
  2. #include <typeinfo>  
  3. class Base  
  4. {  
  5. public:  
  6.  void  B(){}  
  7. };  
  8. class Child1 : public Base  
  9. {  
  10. public:  
  11.  void C(){}  
  12. };  
  13.    
  14. class Child2 : public Base  
  15. {  
  16. public:  
  17.  void C(){}  
  18. };  
  19. void main()  
  20. {  
  21.     Base* Cast = new Child1();  
  22.     Base* Cast2 = new Child2();  
  23.     printf( "%s \n"typeid(*Cast).name() );  
  24.     printf( "%s \n"typeid(*Cast2).name() );  
  25. }   


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

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

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



  1. #include <stdio.h>  
  2. #include <typeinfo>  
  3. class Base  
  4. {  
  5. public:  
  6.  void  B(){}  
  7.  virtual void a(){}  
  8. };  
  9. class Child1 : public Base  
  10. {  
  11. public:  
  12.  void C(){}  
  13.  virtual void a(){}  
  14. };  
  15.    
  16. class Child2 : public Base  
  17. {  
  18. public:  
  19.  void C(){}  
  20.  virtual void a(){}  
  21. };  
  22. void 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. }  

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

수행결과는

"Class Child1"

"Class Child2"

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

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


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


마치며

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

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

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

[출처] furyheimdall.springnote.com

'Sunmoon_BIT > C++ programing' 카테고리의 다른 글

추상클래스 Vs 인터페이스  (0) 2010.10.16
AVL 트리 회전  (0) 2009.12.23
MyVector를 사용한 학생관리 - C++  (0) 2009.11.20
Template - MyVector  (0) 2009.11.19
TEMPLATE - C++  (0) 2009.11.17
:
Sunmoon_BIT/.NET 2010. 4. 6. 01:11

리모팅서비스

서버

클라이언트

-       원격클래스

-       원격객체

-       클라이언트와 통신을 위한

서버채널 개설

 

-       원격참조객체(PROXY객체)

-       서버와의 통신을 위한 채널

 

1.     원격 클래스 디자인 -> 시스템에 등록 -> 서버에서 서비스

2.     클라이언트는 원격시스템에 접속하여 원격서비스를 받는다.

 

원격클래스 : MachalByRefObject 상속

 

// 원격 클래스인 Hello.dll 생성//

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace Hello

{

    public class Hello : MarshalByRefObject

    {

        public Hello()

        {

            Console.WriteLine("Hello 생성자 호출");

        }

        public String SayHello(String name)

        {

            Console.WriteLine("Hello SayHello() 함수 호출, 매개변수{0}", name);

            return "안녕하세요! [" + name + "] ";

        }

 

        ~Hello()

        {

            Console.WriteLine("Hello 소멸자 호출");

        }

    }

}

//HelloSever 만들기

//Hello.dll참조

//참조에서 System.Runtime.Remoting 추가!

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

 

 

using System.Runtime.Remoting.Channels.Tcp;namespace HelloServer

{

    public class HelloServer

    {

        static void Main(string[] args)

        {

            TcpChannel channel = new TcpChannel(9009);
            //채널을 생성한다

            ChannelServices.RegisterChannel(channel, false);

            //원격 서비스에 채널을 등록한다

            RemotingConfiguration.RegisterWellKnownServiceType(typeof(Hello.Hello), "BaboHello", WellKnownObjectMode.SingleCall);
//원격클래스를 등록한다

            Console.WriteLine("서버를 멈추려면 Enter를 누르세요");

            Console.ReadLine();

 

        }

    }

}

RemotingConfiguration.RegisterWellKnownServiceType

(typeof(참조DLL Namespace.Class), 원격서비스의 이름, 원격객체의 활성화 방식);

 

//클라이언트

//Hello.dll참조

//참조에서 System.Runtime.Remoting 추가!

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;

 

namespace HelloClient

{

    class HelloClient

    {

        static void Main(string[] args)

        {

            TcpChannel channel = new TcpChannel();

            ChannelServices.RegisterChannel(channel, false);

 

            Object obj = Activator.GetObject(typeof(Hello.Hello), "tcp://localhost:9009/BaboHello");

 

            Hello.Hello h = (Hello.Hello)obj;

            Console.WriteLine(h.SayHello("황성노"));

        }

    }

}

 

 

 

 

서버를 실행시키면 아무 반응이 없고 대기하다가 클라이언트를 실행하면

< Object obj = Activator.GetObject(typeof(Hello.Hello), "tcp://localhost:9009/BaboHello");>

를 통해 Hello네임스페이스의 hello클래스를 obj에 가져온다

 

< Hello.Hello h = (Hello.Hello)obj;>

가져온 오브젝트를 Hello네임스페이스의 hello클래스형식으로 변환한다

 

< Console.WriteLine(h.SayHello("황성노"));>

변환한 h를 사용해서 SayHello함수를 호출하면 서버측의 함수가 호출된다

:
Sunmoon_BIT/C# 2010. 4. 3. 02:33

  • F12 : 정의된 곳으로 이동합니다
  •  

  • Ctrl + K  + M : 선언되지 함수를 사용하고 그부분에 대고 누르면 함수 자동생성
  •  

  • Ctrl + J : 사용가능한 함수,변수리스트가 인텔리전스로 뜸
  •  

  • Ctrl + F3 : 단어검색. ctlr+f누르는것보다 해당 단어를 선택하고 Ctrl+F3을 누르면 검색시작하고 F3을 누르면 아래쪽에 위치한 단어를 차례대로 찾아줍니다. 위로찾기는 Shitr+F3
  •  

  • Ctrl + Tap : 클래스간 이동
  •  

  • Shifr + F12 :  단어를 선택하고 해당키를 누르면 기호찾기결과창에 프로젝트내에 해당 단어가 들어간곳을 나타내줍니다

  •  

     

     

    나머지는 해석해보세요

     

    Visual Studio 2008 Hot Keys

     

    Edit

    Edit.CollapseTo-Definitions CTRL + M, O
    Edit.ToggleAllOutlining CTRL + M, L
    Edit.ToggleOutliningExpansion CTRL + M, M
    Edit.StopOutlining CTRL + M, P
    Edit.CommentSelection CTRL + K, C or CTRL + E, C
    Edit.UncommentSelection CTRL + K, U or CTRL + E, U
    Edit.FormatDocument CTRL + K, D or CTRL + E, D
    Edit.FormatSelection CTRL + K, F or CTRL + E, F
    Edit.InsertSnippet CTRL + K, X
    Edit.SurroundWith CTRL + K, S
    Edit.InvokeSnippetFromShortcut TAB
    Edit.CycleClipboardRing CTRL + SHIFT + V
    Edit.Replace CTRL + H
    Edit.ReplaceInFiles CTRL + SHIFT + H
    View.ShowSmartTag CTRL + . Or SHIFT + ALT + F10
    File
    File.NewProject CTRL + SHIFT + N
    File.OpenProject CTRL + SHIFT + O
    Project.AddClass SHIFT + ALT + C
    Project.AddExistingItem SHIFT + ALT + A
    Project.AddNewItem CTRL + SHIFT + A
    Window.ShowEzMDIFileList CTRL + ALT + DOWN ARROW
    Edit.OpenFile CTRL + O
    Intellisense
    Edit.CompleteWord CTRL + SPACE or CTRL + K, W
    Edit.ListMembers CTRL + J or CTRL + K, L
    Edit.QuickInfo CTRL + K, I
    Edit.ParameterInfo CTRL + SHIFT + SPACE or CTRL K, P
    Make Completion List Transparent CTRL
    Navigation
    Edit.FindAllReferences SHIFT + F12 or CTRL + K, R
    Edit.GoToBrace CTRL + ]
    Edit.GoToDefinition F12
    Edit.GoToNextLocation F8
    Edit.IncrementalSearch CTRL + I
    View.ClassViewGo-ToSearch, Combo CTRL + K, CTRL + V
    View.ForwardBrowseContext CTRL + SHIFT + 7
    View.PopBrowseContext CTRL + SHIFT + 8
    View.NavigateBackward CTRL + MINUS SIGN (-)
    View.NavigateForward CTRL + SHIFT + MINUS SIGN (-)
    Edit.FindInFiles CTRL + SHIFT + F
    Edit.FindSymbol ALT + F12
    View.ViewCode F7
    View.ViewDesigner SHIFT + F7
    View.ViewMarkup SHIFT + F7
    Window.MoveToNavigationBar CTRL + F2
    Edit.Find CTRL + F
    Edit.GoTo CTRL + G
    Edit.GoToFindCombo CTRL + /
    Window
    View.ClassView CTRL + W, C
    View.CodeDefinitionWindow CTRL + W, D
    View.Command-Window CTRL + W, A
    View.ErrorList CTRL + W, E
    View.ObjectBrowser CTRL + W, J
    View.Output CTRL + W, O
    View.PropertiesWindow CTRL + W, P
    View.SolutionExplorer CTRL + W, S
    View.TaskList CTRL + W, T
    View.Toolbox CTRL + W, X
    View.ServerExplorer CTRL + W, L
    Window.CloseToolWindow SHIFT + ESC
    Data.ShowDataSources SHIFT + ALT + D
    Window.CloseDocument, Window CTRL + F4
    Window.NextDocument, WindowNav CTRL + TAB
    Refactor
    Refactor.EncapsulateField CTRL + R, E
    Refactor.ExtractInterface CTRL + R, I
    Refactor.ExtractMethod CTRL + R, M
    Refactor.PromoteLocalVariabletoParameter CTRL + R, P
    Refactor.RemoveParameters CTRL + R, V
    Refactor.Rename CTRL + R, R or F2
    Refactor.ReorderParameters CTRL + R, O
    Debugging
    Debug.Autos CTRL + D, A
    Debug.CallStack CTRL + D, C
    Debug.Immediate CTRL + D, I
    Debug.Locals CTRL + D, L
    Debug.QuickWatch CTRL + D, Q
    Debug.Start F5
    Debug.StartWithoutDebugging CTRL + F5
    Debug.StepInto F11
    Debug.StepOut SHIFT + F11
    Debug.StepOver F10
    Debug.StopDebugging SHIFT + F5
    Debug.ToggleBreakpoint F9
    Debug.Watch CTRL + D, W
    Debug.EnableBreakpoint CTRL + F9
    Make Datatip Transparent [CTRL]
    Build
    Build.BuildSolution F6 or CTRL + SHIFT + B
    Build.BuildSelection

    SHIFT + F6

     

    'Sunmoon_BIT > C#' 카테고리의 다른 글

    정규식 기호표  (0) 2010.04.19
    Visual Studio 2008 자동 줄맞춤  (0) 2010.04.03
    Effective C#  (0) 2010.04.01
    Sealed Class , Sealed Method  (0) 2010.03.29
    Deligate [대리자]  (0) 2010.03.26
    :