컨테이너 클래스처럼, 당신은 (템플릿 인수의 형태 등) 구축 비교기 클래스를 통과 할 수있는에 생성자를 제공합니다. 당신이있는 경우 즉, :
class Base {};
class Child : public Base {};
std::list <Base> myList;
std::list <Base> *pMyList;
그런 다음
myList
의 요소 만 (참조) 타입
Base
의 객체로 액세스 할 수 있습니다.
Base
유형의 요소 (예 :
push_back
,
emplace_back
)를 저장하고 참조/사본 (예 :
front
또는 반복자를 통해)을 가져올 수 있습니다 (예 :
cppreference/list 참조). 이제
push_back
에서 살펴 보자 :
value_type
당신이
std::list
에 전달 된 첫 번째 템플릿 매개 변수가
void push_back(const value_type&);
. 귀하의 경우는 PartitionT < CompareJobReady, CompareJobRunning >
이고, 위 예의 경우 Base
입니다. push_back
실제로 복사본 복사본을 전달하고 그 복사본을 새 요소로 복사합니다. 왜 그런가요? 새 요소는 목록에서 소유 할 수 있기 때문입니다. 목록 자체가 파괴되면 목록은이 요소를 파괴 할 수 있으며 두 목록을 이동/교환하면 다른 목록으로 전달할 수 있습니다. 요소가 복사되지 않고 외부에서 소멸 된 경우 목록에 파괴 된 요소가 포함됩니다. 목록에서 제공하는 보증이 깨집니다 (매우 좋지는 않을 것입니다).
또 다른 예 (단순하지만 매우 정확하지는 않음) : list
은 할당자를 통해 요소에 메모리를 할당합니다. 기본 할당자는 std::allocator<Base>
입니다. Base
유형의 객체를 저장하는 데 필요한만큼 요소의 메모리 만 할당합니다.
당신이 pMyList = new std::list <Child>;
같은 "std::list<Base>
포인터"왼쪽이 유형 인 반면, "std::list<Child>
포인터의"에서 오른쪽 결과를 할
.
std::list<Base>
은 std::list<Child>
에서 상속되지 않거나 변환을 정의하지 않으므로이 두 유형은 관련이 없습니다.이것이 왜 좋은지에 대한 몇 가지 이유가 있습니다. 하나는 범용 프로그래밍이 어떤 유형을 다루어야 하는지를 요구한다는 것입니다. 다형성 (Polymorphism)은 추상화이므로 컴파일 타임에 처리 할 유형을 알 필요도 없습니다.
C++의 다형성은 포인터 또는 참조를 통해 작동합니다. 이 유형의 불가지론 목록의 일부 Child
객체 (예 : 그것은 단지 Base
유형을 알고) 준비하려는 경우 그래서, 당신은 포인터로 저장해야합니다 :
std::list < std::shared_ptr<Base> > myList2;
myList2.push_back(new Child); // better not use, there's a caveat (1)
// approach w/o this caveat
std::shared_ptr<Base> pNewChild(new Child); // or make_shared
myList2.push_back(pNewChild);
주 나는 여기에 shared_ptr
를 사용, 즉 더 나은 목적에 맞는 경우뿐만 아니라 unique_ptr
를 사용할 수 있지만 원시 ptrs를 사용해서는 안 :이 myList2
이 shared_ptr
요소를 소유하고 shared_ptr
공유 소유권 (유형 자료의) 객체를 보유하고, myList2
간접적으로 Child
를 소유 목록에있는 ptrs를 저장하는 객체. 원시 ptrs는 소유권을 나타내지 않으므로 예를 들어 누구를 파기해야할지 분명하지 않습니다. "Rule of Zero"에 대해 더 자세히 읽어보십시오.
(1)이 예에는 영향을 미치지 않지만주의 사항이 있습니다 (boost 참조). 당신이 정말로 어딘가에 비교 자 클래스를 선택하여 제네릭 프로그래밍을 수행 할 경우
, 당신은 "컴파일 시간에 충실해야한다"귀하의 목록에있는 유형 (*p
의 유형) list<Base>
아니라 일반적인 고정되어서는 안된다 (템플리트 사용) 및 사용하는 모든 알고리즘은 generic이어야합니다. 일반 프로그래밍은 컴파일 타임에 코드를 만드는 것이므로 일반 프로그래밍과 유형의 런타임 선택을 혼합 할 수는 없습니다 (간단히 *).
* RTTI를 남용하여 매우 느려지는 해킹이 있습니다.
표준 라이브러리의'std :: list'입니까? – dyp
네, 말씀 드리지 않으면 미안합니다. – user1809140