포인터, 스마트 포인터 또는 공유 포인터? [복제]
이 질문에는 이미 답변이 있습니다.
- 스마트 포인터 란 무엇이며 언제 사용해야합니까? 답변 13 개
나는 일반적인 포인터로 프로그래밍하고 있지만 스마트 포인터를 구현하는 Boost와 같은 라이브러리에 대해 들었습니다. 또한 Ogre3D 렌더링 엔진에는 공유 포인터가 많이 사용되는 것을 보았습니다.
세 가지의 차이점은 정확히 무엇입니까? 그냥 유형을 계속 사용해야합니까?
Sydius는 유형을 상당히 잘 설명했습니다.
- 일반적인 포인터 는 그저 메모리의 어떤 부분을 가리 킵니다. 누가 그것을 소유합니까? 의견 만 알려줄 것입니다. 누가 해방합니까? 바라건대 소유자.
- 스마트 포인터 는 여러 유형을 포괄하는 포괄적 인 용어입니다. RAII 패턴 을 사용하는 범위가 지정된 포인터를 의미한다고 가정합니다 . 포인터를 감싸는 스택 할당 객체입니다. 범위를 벗어나면 줄 바꿈 포인터에서 delete를 호출합니다. 포함 된 포인터를 "소유"하여 특정 시점에서 삭제를 담당합니다. 다른 메소드로 전달 하고 포인터 를 해제 하여 다른 사람이 소유 할 수 있도록 랩핑 한 포인터에 대한 원시 참조를 얻을 수 있습니다 . 복사하는 것은 의미가 없습니다.
- 공유 포인터 는 스택을 할당 한 객체로, 포인터를 감싸서 누가 누구인지 알 필요가 없습니다. 메모리의 객체에 대한 마지막 공유 포인터가 파괴되면 랩핑 된 포인터도 삭제됩니다.
언제 사용해야합니까? 범위가 지정된 포인터 또는 공유 포인터를 많이 사용합니다. 응용 프로그램에서 몇 개의 스레드가 실행되고 있습니까? 대답이 "잠재적으로 많으면"공유 포인터는 어디에서나 사용하면 성능 병목 현상이 될 수 있습니다. 공유 포인터를 작성 / 복사 / 파괴하는 이유는 원 자성 작업이어야하기 때문에 많은 스레드가 실행중인 경우 성능이 저하 될 수 있습니다. 그러나 항상 그런 것은 아닙니다. 테스트만으로도 확실하게 알 수 있습니다.
공유 포인터에 대한 논쟁 (내가 좋아하는)이 있습니다.이를 사용하면 프로그래머가 포인터를 소유 한 사람을 무시할 수 있습니다. 이로 인해 순환 참조 (자바는이를 감지하지만 공유 포인터로는 감지 할 수 없음) 또는 대규모 코드 기반의 일반적인 프로그래머 게으름으로 까다로운 상황이 발생할 수 있습니다.
범위가 지정된 포인터를 사용해야하는 두 가지 이유가 있습니다. 첫 번째는 간단한 예외 안전 및 정리 작업을위한 것입니다. 예외에 상관없이 객체가 정리되도록 보장하고 해당 객체를 스택 할당하지 않으려면 범위가 지정된 포인터에 넣으십시오. 작업이 성공하면 공유 포인터로 자유롭게 전송할 수 있지만 그 동안 범위가 지정된 포인터로 오버 헤드를 저장하십시오.
다른 경우는 명확한 객체 소유권을 원할 때입니다. 어떤 팀은 이것을 선호하지만 어떤 팀은 그렇지 않습니다. 예를 들어, 데이터 구조는 내부 객체에 대한 포인터를 반환 할 수 있습니다. 범위가 지정된 포인터에서는 약한 참조로 취급되어야하는 원시 포인터 또는 참조를 반환합니다. 포인터를 소유 한 데이터 구조가 삭제 된 후 해당 포인터에 액세스하면 오류가 발생하며이를 삭제하는 것은 오류입니다. 공유 포인터에서 소유 객체는 누군가가 여전히 핸들을 보유하고있는 경우 반환 된 내부 데이터를 파괴 할 수 없습니다. 이렇게하면 리소스가 필요 이상으로 더 오래 열려 있거나 코드에 따라 훨씬 더 나빠질 수 있습니다.
"스마트 포인터"라는 용어 에는 공유 포인터, 자동 포인터, 잠금 포인터 및 기타가 포함됩니다. 당신은 똑똑한 포인터가 아니라 자동 포인터 (더 이상 "소유 포인터"라고도 함)를 말하려고했습니다.
벙어리 포인터 (T *)는 최고의 솔루션이 아닙니다. 그것들은 당신이 명백한 메모리 관리를하도록하는데, 그것은 장황하고, 오류가 발생하기 쉽고 때로는 거의 불가능합니다. 그러나 더 중요한 것은 그들은 당신의 의도를 알리지 않습니다.
자동 포인터는 파괴시 포인트를 삭제합니다. 배열의 경우 벡터 및 deque와 같은 캡슐화를 선호합니다. 다른 객체의 경우 힙에 객체를 저장할 필요가 거의 없으며 로컬 및 객체 구성 만 사용하십시오. 팩토리 및 다형성 리턴과 같은 힙 포인터를 리턴하는 함수를 사용하면 자동 포인터가 여전히 필요합니다.
공유 포인터는 마지막 공유 포인터가 파괴 될 때 포인트를 삭제합니다. 이는 예상 수명과 소유권이 상황에 따라 크게 다를 수있는 간편한 개방형 스토리지 체계를 원할 때 유용합니다. (원자) 카운터를 유지해야하므로 자동 포인터보다 약간 느립니다. 어떤 사람들은 공유 포인터가 시스템을 설계 할 수없는 사람들을위한 것이라고 자신을 판단합니다.
공유 포인터에 대한 필수 대응 물은 약한 포인터도 찾아보십시오.
스마트 포인터는 범위를 벗어난 후에 스스로 정리됩니다 (따라서 대부분의 메모리 누수에 대한 두려움을 제거합니다). 공유 포인터는 포인터의 인스턴스 수를 카운트하고 카운트가 0에 도달 할 때만 메모리를 정리하는 스마트 포인터입니다. 일반적으로 공유 포인터 만 사용하십시오 (그러나 올바른 종류를 사용해야합니다-배열에 다른 포인터가 있습니다). 그들은 RAII 와 많은 관련이 있습니다.
메모리 누수를 방지하기 위해 가능하면 스마트 포인터를 사용할 수 있습니다. C ++에는 기본적으로 2 가지 유형의 스마트 포인터가 있습니다.
- 계산 된 참조 (예 : boost :: shared_ptr / std :: tr1 : shared_ptr)
- 비 참조 카운트 (예 : boost :: scoped_ptr / std :: auto_ptr)
가장 큰 차이점은 scoped_ptr은 참조 카운트되지 않은 스마트 포인터를 복사하고 std :: 컨테이너에서 사용할 수 있다는 것입니다. 비 참조 카운트 포인터는 오버 헤드가 거의 없거나 오버 헤드가 전혀 없습니다. 참조 카운팅은 항상 일종의 오버 헤드를 유발합니다.
(auto_ptr을 피하는 것이 좋습니다. 잘못 사용하면 심각한 결함이 있습니다)
Sydius의 답변에 약간을 추가하기 위해 스마트 포인터는 종종 많은 오류를 쉽게 잡아서보다 안정적인 솔루션을 제공합니다. 원시 포인터는 일부 성능 이점이 있으며 특정 상황에서 더 유연 할 수 있습니다. 특정 타사 라이브러리에 연결할 때 원시 포인터를 사용해야 할 수도 있습니다.
참고 URL : https://stackoverflow.com/questions/417481/pointers-smart-pointers-or-shared-pointers
'development' 카테고리의 다른 글
레일에서 루비 (0) | 2020.07.24 |
---|---|
LINQ, Where () 및 FindAll () (0) | 2020.07.24 |
입력 옆에 레이블을 형태로 정렬 (0) | 2020.07.24 |
코드 랩 IntelliJ? (0) | 2020.07.24 |
Windows가 fork ()해야 할 가장 가까운 것은 무엇입니까? (0) | 2020.07.24 |