문제

나는 동적 언어에서 기본 유형으로 사용될 변형 클래스를 작성했습니다. 이 클래스는 궁극적으로 256가지 다른 유형의 값을 허용합니다(헤더는 부호 없는 바이트이며 실제로는 20개만 사용됨).이제 유형 간 캐스팅/변환을 구현하고 싶습니다.

나의 초기 생각은 조회 테이블이었지만 필요한 메모리 양으로 인해 구현하기가 비실용적이었습니다.

대안은 무엇입니까?현재 저는 다른 사람들의 연구와 제안을 통해 세 가지 추가 방법을 고려하고 있습니다.

  1. 유형을 숫자, 컬렉션 등 더 큰 하위 집합으로 그룹화합니다.
  2. CanCast(from, to) 및 Cast(Variant) 메서드가 있는 변환 인터페이스를 만들고 해당 인터페이스를 구현하는 클래스를 목록에 추가할 수 있도록 허용한 다음 변환 클래스 중 하나라도 캐스트를 수행할 수 있는지 확인할 수 있습니다.
  3. (1)과 유사하지만 여러 개의 마스터 유형을 만들고 캐스팅은 원래 유형에서 마스터 유형으로, 다시 최종 유형으로 2단계 프로세스입니다.

가장 좋은 시스템은 무엇일까요?

편집하다:나는 여전히 최고의 시스템에 대해 확신이 없기 때문에 현상금을 추가했습니다. 현재 답변은 매우 좋으며 확실히 +1을 얻었습니다. 그러나 이 작업을 수행하고 가장 좋은 방법이 무엇인지 말할 수 있는 사람들이 분명 있을 것입니다.

도움이 되었습니까?

해결책

내 시스템은 매우 "무거우"지만(코드가 많음) 매우 빠르고 기능이 풍부합니다(크로스 플랫폼 C++).당신의 디자인이 얼마나 멀리 가고 싶은지 잘 모르겠지만, 제가 한 일의 가장 큰 부분은 다음과 같습니다.

DatumState - "유형"에 대한 "열거형"과 다음을 포함한 모든 기본 유형 간의 "결합"인 기본 값을 보유하는 클래스 void*.이 클래스는 모든 유형에서 분리되며 모든 기본/기본 유형 및 "참조"에 사용할 수 있습니다. void* 유형." 이후enum"도 있습니다"VALUE_OF" 그리고 "REF_TO" 컨텍스트에서 이 클래스는 다음을 "완전히 포함"하는 것으로 나타날 수 있습니다. float (또는 일부 기본 유형) 또는 "참조하지만 소유하지 않음" float (또는 일부 기본 유형).(실제로 "VALUE_OF", "REF_TO", 그리고 "PTR_TO" 컨텍스트를 사용하여 논리적으로 저장할 수 있습니다. , ㅏ null이 될 수 없는 참조, 또는 null일 수도 있고 아닐 수도 있는 포인터, 그리고 나는 그것을 해야 한다는 것을 알고 있습니다 삭제 여부.)

Datum - 전체를 포함하는 클래스 DatumState, 그러나 다양한 "잘 알려진" 유형(예: MyDate, MyColor, MyFileName, 등) 이러한 잘 알려진 유형은 실제로 void* 안에 DatumState 회원.그러나 "enum" 부분의 DatumState "을 가지고있다VALUE_OF" 그리고 "REF_TO" 문맥에 따라 "를 나타낼 수 있습니다.pointer-to-MyDate" 또는 "value-of-MyDate".

DatumStateHandle - (잘 알려진) 유형(예: MyDate, MyColor, MyFileName, 등) 이는 에서 사용하는 접근자입니다. Datum 잘 알려진 유형에서 상태를 추출합니다.기본 구현은 대부분의 클래스에서 작동하지만 액세스에 대한 특정 의미를 가진 클래스는 단지 이 템플릿 클래스에 있는 하나 이상의 멤버 함수에 대한 특정 템플릿 매개변수화/구현을 재정의할 뿐입니다.

Macros, helper functions, and some other supporting stuff - 잘 알려진 유형의 "추가"를 단순화하기 위해 Datum/Variant, 로직을 몇 개의 매크로로 중앙 집중화하고, 연산자 오버로딩과 같은 일부 지원 기능을 제공하고, 내 코드에 몇 가지 다른 규칙을 설정하는 것이 편리하다는 것을 알았습니다.

이 구현의 "부작용"으로 참조 및 값 의미 체계, 모든 유형에 대한 "null" 옵션, 모든 유형에 대한 이기종 컨테이너 지원 등 수많은 이점을 얻었습니다.

예를 들어, 정수 세트를 생성하고 이를 인덱싱할 수 있습니다.

int my_ints[10];
Datum d(my_ints, 10/*count*/);
for(long i = 0; i < d.count(); ++i)
{
  d[i] = i;
}

마찬가지로 일부 데이터 유형은 문자열 또는 열거형으로 색인화됩니다.

MyDate my_date = MyDate::GetDateToday();
Datum d(my_date);
cout << d["DAY_OF_WEEK"] << endl;
cout << d[MyDate::DAY_OF_WEEK] << endl; // alternative

항목 세트(기본적으로) 또는 세트 세트를 저장할 수 있습니다.Datums (각 항목 포장).두 경우 모두 재귀적으로 "풀기"할 수 있습니다.

MyDate my_dates[10];
Datum d(my_dates, 10/*count*/);
for(long i = 0; i < d.count(); ++i)
{
  cout << d[i][MyDate::DAY_OF_WEEK] << endl;
}

누군가는 내 "REF_TO" 그리고 "VALUE_OF" 의미론은 과잉이지만 "set-unwrapping"에는 필수적이었습니다.

내가 이런 짓을 했어"Variant"는 9개의 서로 다른 디자인을 가지고 있고 내 현재는 "가장 무겁다"(대부분의 코드). 사용.

내 디자인의 "단점"은 다음과 같습니다.

  1. 개체는 다음을 통해 액세스됩니다.static_cast<>() 에서 void*(유형-안전하고 상당히 빠르지 만 간접이 필요합니다.그러나 부작용은 디자인이 "의 저장을 지원한다는 것입니다.null".)
  2. 잘 알려진 유형이 Datum 인터페이스 (그러나 사용할 수 있습니다 DatumState 잘 알려진 유형 API를 원하지 않는다면).

디자인에 관계없이 다음을 권장합니다.

  1. "를 사용하세요.enum"또는 당신에게 말할 것"유형",,"".(나는 당신이 그것들을 하나로 압축 할 수 있다는 것을 알고 있습니다. "int"또는 비트 포장을 가진 무언가이지만, 새로운 유형이 소개 될 때 느리게 접근하고 매우 까다 롭습니다.)

  2. 유형 별 (재정의) 처리를위한 메커니즘 (사소한 유형을 처리한다고 가정)으로 템플릿 또는 작업을 중앙 집중화하는 것에 의존합니다.

게임 이름은 "새로운 유형 추가 시 유지 관리 단순화" (또는 적어도 그것은 나를 위한 것이었습니다).좋은 기말 보고서처럼, 다시 쓰고, 다시 쓰고, 다시 쓰면 아주 좋은 생각입니다. 보유 또는 증가 당신의 기능은 끊임없이 제거하다 시스템을 유지하는 데 필요한 코드(예: 기존 유형에 새로운 유형을 적용하는 데 필요한 노력 최소화) Variant 하부 구조).

행운을 빌어요!

다른 팁

비슷한 일을했습니다.

'헤더'에 다른 바이트를 추가하여 실제로 저장하는 유형을 표시 할 수 있습니다.

C 스타일 프로그래밍 언어의 예 : 라코 디스

이것은 제안 일 뿐이며 테스트되지 않았습니다.

이미 계산을 완료했지만 조회 테이블에 필요한 메모리 양은 그다지 가 아닙니다.

유형이 호환되는지 확인해야하는 경우 (256 * 256) / 2 비트가 필요합니다.이를 위해서는 4k의 메모리가 필요합니다.

변환 함수에 대한 포인터도 필요하면 (256 * 256) / 2 개의 포인터가 필요합니다.이를 위해서는 32 비트 시스템에서 128k 메모리가 필요하고 64 비트 시스템에서 256k 메모리가 필요합니다.낮은 수준의 주소 레이아웃을 수행하려는 경우 32 비트 및 64 비트 컴퓨터에서 64k로 줄일 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top