포인터의 벡터 템플릿 청소 함수는 "정의되지 않은 참조"메시지로 컴파일하지 못합니다.

StackOverflow https://stackoverflow.com/questions/914460

  •  06-09-2019
  •  | 
  •  

문제

내 프로그램의 경우 나는 내가 가진 다양한 std :: 포인터 벡터를 지우기 위해 작은 기능을 만들었습니다.

template <class S>
void clearPtrVector(std::vector<S*> &a,int size)
{
    for(size_t i = 0; i < size; i++)
         delete a[i];

    a.clear();
}

이 기능을 파괴자로 호출 할 때 다음과 같은 문제를 해결했을 것입니다.

clearPtrVector(neurons,neurons.size());

다음과 같은 정의되지 않은 참조를 두 번받습니다.

undefined reference to `void clearPtrVector<Neuron>(std::vector<Neuron*,std::allocator<Neuron*> >&, int)'

나는 STD :: 할당자가 무엇인지 잘 알고 있지 않다는 것을 인정해야하므로 문제가 무엇인지 추측 할 수 없습니다. 모든 도움은 정말 감사합니다. 미리 감사드립니다!

-lefteris

도움이 되었습니까?

해결책

핫 수정

대신 다음을 작성하십시오.

  template <class Vector>
  void clearPtrVector(Vector &a)
  {
    for(size_t i = 0; i < a.size(); i++)
         delete a[i];

    a.clear();
  }

템플릿을 사용하기 전에 컴파일러가 볼 수있는 곳에 템플릿을 정의해야합니다. 선언을 작성하지 않으면 안전해야합니다. 그렇지 않으면 컴파일 오류가 발생해야합니다. 어떤 이유로 든 신고서를 작성하는 경우 필요에 따라 모든 곳에서 정의를 포함하도록 두 번주의하십시오.

재 설계

즉, 적절한 솔루션은 디자인을 다시 생각하고 파괴를 올바르게 처리 할 컨테이너를 사용하여 수동으로 할 필요가없고, 지루하고, 필요한 경우 거의 불가능합니다. 예외 안전. 사용 std::shared_ptr 원시 포인터 대신, 또는 std::auto_ptr 그들을 잡을 수있는 컨테이너로 (std::vector 저장할 수 없습니다 auto_ptr 값). 하나의 가능한 솔루션은 사용하는 것입니다 포인터 컨테이너를 부스트하십시오

다른 팁

ClearPtrVector 구현이 헤더 파일에 있습니까? 별도의 .CPP 파일에 있으면 링커가 찾을 수 없기 때문입니다.

몇 가지:

원래 코드에서는 크기를 전달하지 마십시오. 벡터에서 가져 오기 :

template <class S>
void clearPtrVector(std::vector<S*> &a)
{
    for(size_t i = 0; i < a.size(); ++i)
    {
         delete a[i];
    }

    a.clear();
}

둘째, 가리키는 유형이 아니라 벡터 자체를 전달합니다.

template <class Vector>
void clearPtrVector(Vector &vec)
{
    for(size_t i = 0; i < vec.size(); ++i)
    {
         delete vec[i];
    }

    vec.clear();
}

셋째, 그 오류는 .cpp 파일에 배치 된 것처럼 들립니다. 기능을 처음 호출 할 때 코드가 생성됩니다. 즉, 컴파일러가 함수의 정의를 알아야합니다. 기능을 헤더 파일로 이동하여 컴파일러가 찾을 수 있습니다.

마지막으로, 이것에 더 적합한 것을 사용하는 것을 고려하십시오.

헤더 파일 (.h, *.hpp) 에이 함수가 있는지 확인하십시오. 헤더 파일에 프로토 타입이있는 소스 파일에 정의되지 않은 참조 링커 오류가 발생하기 때문입니다.

정의되지 않은 참조 오류는 컴파일러가 함수의 참조를 찾았지만 링커는 객체 파일간에 해당 함수의 참조를 찾지 못했음을 의미합니다. 모든 템플릿 함수는 헤더 파일에 정의되어야하므로 컴파일러가 기능을 사용하는 소스 파일에 넣을 수 있습니다.

재 설계는 복제본이 아닙니다청소 -STL-List-Vector-of-Pointers

주목

스마트 포인터 중 하나를 사용하지 않으면 사용하십시오. 부스트 :: Checked_delete 불완전한 유형을 삭제하지 않도록 삭제하는 대신 함수.

당신의 첫 번째 질문에 대한 내 대답에 제공했듯이 https://stackoverflow.com/questions/891913?sort=newest, 한 가지 대답은 다음과 같습니다.

template <class C> void FreeClear( C & cntr ) {
    for ( typename C::iterator it = cntr.begin(); 
              it != cntr.end(); ++it ) {
        delete * it;
    }
    cntr.clear();
}

모든 컨테이너 유형에 적합합니다. 크기 매개 변수는 제공되지 않았지만 컬렉션에서 제공됩니다.이 기능을 설계하는 올바른 방법이며, 별도의 값으로 크기를 제공하면 재난으로 이어질 수 있습니다.

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