다양한 멤버가있는 데이터 구조의 문제를 해결하는 데는 여러 가지 방법이 있으며 가장 좋은 방법은 사용 방법에 따라 다릅니다.
가장 확실한 것은 상속을 사용하는 것입니다. 당신은 기본 클래스에서 모든 가능성을 도출 :
struct base_struct {
int id;
std::string name;
};
list<base_struct*> some_list;
struct some_struct : public base_struct {
double metricA;
};
struct some_other_struct : public base_struct {
int metricB;
};
base_struct *s1 = new some_struct;
s1->id = 1;
// etc
base_struct *s2 = new some__other_struct;
s2->id = 2;
// etc
some_list.push_back(s1);
some_list.push_back(s2);
까다로운 비트가 당신이 다시 밖으로 요소를 얻을 때, 당신의 경우 적절하게 확인해야한다는 것입니다.type_info
사용하여 주조하기 전에
some_struct* ss = dynamic_cast<some_struct*>(some_list.front());
당신은 이름을 조회 할 수 있습니다 : dynamic_cast
는 형태 보증 된 방법으로이 작업을 수행 할 수 있습니다
typeid(*some_list.front()).name();
주를이 두 일반적으로 OK입니다 RTTI, 건물이 필요하다는 있지만, 특히 RTTI는 성능 비용이 많이 들고, 특히 템플릿이 광범위하게 사용되는 경우 메모리 풋 프린트를 부 풀릴 수 있습니다.
이전 프로젝트에서 우리는 boost any을 사용하여 비슷한 것을 처리했습니다. any
의 장점은 서로 파생되지 않은 유형을 혼합 할 수 있다는 것입니다. 돌이켜 보면, 그때까지 유형 검사가 연기되기 때문에 런타임에 오류가 발생하기 쉽도록 코드를 작성했기 때문에 다시 시도 할 수 있을지 확신 할 수 없습니다. . (이뿐만 아니라 dynamic_cast
접근 방식의 사실이다 나쁜 오래된 C 일에서
, 우리는 union
이 같은 문제 해결 : 다시
struct base_struct {
int id;
std::string name;
union { // metricA and metricB share memory and only one is ever valid
double metricA;
int metricB;
};
};
을, 당신은 당신이 처리해야하는 문제가
STL 이전 시대에는 많은 컨테이너 시스템이 을 사용하도록 작성되어 사용자에게 언제 다시 캐스팅해야하는지 알았습니다. 이론적으로 말하면 list<void*>
하지만 검색어를 입력 할 방법이 없습니다.
편집 : 절대, void*
방법을 사용하십시오!
왜 목록이 고정 크기가 아니므로 "항목 수"가 중요한지는 분명하지 않습니다. –
누군가가 목록을 사용하지 않고 고정 된 수의 항목 만 지원하는 솔루션을 권장 할 수 있기 때문에 나는 그 말을했습니다. – user396404
이러한 데이터 구조를 만들 수 있다고 가정합니다. 당신은 그걸로 무엇을 할 것입니까? 의사 코드와 같은 C++에서 의도 된 사용 예를 보여줄 수 있습니까? –