2012-02-28 5 views
3

나는 여기에 도전의 대상이있다. 나는 미래의 프로젝트를위한 연습과 유틸리티 킷으로 리플렉션 라이브러리에서 일하고 있습니다. 그것을 작동 시키려면, 나는 방해받지 않는 것이 불가피하다는 것을 이미 받아 들였고 귀중한 반성 데이터를 얻기 위해 클래스의 몸체에 적어도 약간의 코드를 추가해야 할 것입니다.리플렉션 구현 : 클래스의 부모를 찾는 방법

그러나 가능한 한 미니멀리즘을 원합니다. 그래서, 기존의 구현을 연구 한 후에, 저에게 맞는 개념을 발견했습니다. 단순화하기 위해, 패턴은 다음과 같습니다

class Base 
{ 
    int baseFoo; 
    double baseBar[5]; 
    RTTINFO(baseFoo, baseBar); 
}; 

(...) 

Base sth; 
std::cout << TypeInfo(sth).variables[0].name; << std::endl; 
// I don't mind if the way of accessing the type info changes totally 

일부 제네릭 프로그래밍을 사용하여, 나는이 RTTINFO 매크로 및 건물 유형의 정보 구조 뒤에 같은 것을 숨기는 꽤 많이 얻을 수 있습니다. 나는 종류, 이름, 배열 크기 등을 검색 할 수 있습니다하지만이처럼, 한 단계를 가서 상속을 소개 할 때 :

다음
class Derived : public Base 
{ 
    std::string foo; 
    char* bar; 
    /* RTTIPARENT(Base); <-- I want to avoid this */ 
    RTTINFO(foo, bar); 
}; 

나는 자료를 명시 할 방지하고 여전히에 들어갈 수 있기를 원하는 것 그것의 일원의 RTTI. BaseRTTINFO(...)Derived에 대한 힌트를 섞어서 가능할 수 있기를 바랍니다. 그럼 .. 거기 있니?

주요 요구 사항은 다음과 같습니다

  1. 가 난 아무데도 기본 클래스하지만 언어 정의 위치를 ​​지정하지 않습니다. 그리고 나는 어떤 매크로에서든지 class Derived : public Base을 감싸고 싶지 않다.
  2. RTTIINFO은 영향을받는 클래스에 필요한 언어 및 메모리 바이어스를 추가 할 수 있습니다.
  3. 내가 원한다면 RTTINFO 매크로에 넣을 수 있습니다. 필요하다면 엄청난 양의 코드도 넣을 수 있습니다.
  4. Base와 Derived 모두 매우 동일한 RTTINFO 매크로를 사용합니다.이 매크로는 물론 추론에서 다시 사용할 수 있습니다. 다중 상속 문제를 버리자, 단일 상속은 충분히 복잡해 보인다.
  5. Base의 RTTI에 액세스 할 필요는 없습니다. RTTI 데이터를 처리하는 다른 외부 도우미 클래스/함수 일 수도 있습니다. 그러나 개인 멤버 변수를 지원해야합니다.
  6. 저는 컴파일과 런타임 비용에 신경 쓰지 않습니다. 상속 트리 만들기, 모든 기존 클래스 폴링, 런타임에 수행해야하는 모든 계산 등의 계산이있는 경우 항상 프로그램의 초기화 단계로 이동할 수있는 방법이 있습니다. 그래서 나를 위해 큰 문제가되지 않습니다.
  7. 가능한 경우 언어 지원 RTTI를 사용하지 마십시오. 일부 프로젝트에서는 해제해야합니다. 어쨌든, 나는 그것으로도 해결책을 찾지 못했습니다.
  8. 추가 컴파일 단계를 추가 할 수 없습니다.

하나의 참고 : 아마 type_info::before()을 사용할 수 있지만 일반적인 컴파일러에서 작동한다고하더라도 C++ 표준은 여기에서 상속 관계에 의존 할 수 없다고 말합니다.

의견을 보내 주셔서 감사합니다.

앤드류

+1

매크로에서 현재 클래스 이름을 어떻게 구합니까? –

+5

Reflection은 전기 톱이 치과 의사의 진료에 속한만큼 C++ "미래를위한 유틸리티 키트"에 속합니다. –

+0

정확하게, 어떤 종류의 리플렉션/타입 정보를 원한다면 너무 많은 매크로로 끝나지 않아 유용하지 않을 것입니다. G 객체를 보자. – farnoy

답변

3

당신은 현재의 C++ 03 또는 C++ 11 컴파일러 (심지어 C++ (11)가 진짜 리플렉션이 없기 때문에) 전체 반사가되지 않습니다.

당신은 당신은 당신의 C++ 컴파일러를 확장 할 수

일부 메타 클래스 코드 (좋은 예로 Qt MOC보고)를 생성 할 수 있습니다. GCC 인 경우 플러그인 또는 MELT 확장 프로그램을 만드는 것이 좋습니다.

+0

이것이 내가 8을 추가 한 이유입니다.) 필자에게 새로운 컴파일 단계를 추가하는 것은 리플렉션을 작동시키려는 시도를 포기해야하는 많은 단점이 있습니다. – Andrew

+0

그러면 Qt처럼 C++ 메타 클래스 코드를 생성해야합니다. 아마도'QObject' (GUI가없는 QCore)를 사용해 보셨습니까 ?? –

+0

제안을 주셔서 감사합니다. 실제로 QObject가 할 것이지만, 여전히 그것을 달성하기 위해서는'moc'이 필요합니다. 명확하지 않았습니다. '추가 컴파일 단계'로 코드 생성 및 사전 처리를 의미합니다. 그러나 디버그 구성에서만 Qt 확장을 사용하고 프로젝트 (SCM 포함)를 동시에 유지 관리 할 수 ​​있다고 생각합니까? 아니면 가치가 있지 않습니까? – Andrew

2

일종의 DSL (도메인 특정 언어)을 설정하고 코드 작성 프레임 워크를 사용하여 해당 DSL의 클래스 설명을 기반으로 반사 작업을 수행하는 코드 생성을 고려해 볼 수 있습니다. 이것은 아마도 데이터 컨테이너와 상속 부분에 대해서만 작동하고 행동 부분 (예 : 메소드)에 대해서는 작동하지 않지만 어쨌든 대부분의 Java 옹호자는 빈약 한 객체 모델을 선호하기 때문에 이러한 경향에 완벽하게 부합합니다.

C++에는 진정한 다중 상속이 있기 때문에 이러한 단점을 극복하고 생성 된 클래스에서 행동 클래스를 파생시킬 수 있습니다.

스테판

관련 문제