일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 보안
- 자바스크립트
- 버전관리
- 코딩
- 데이터분석
- 빅데이터
- 2
- 컴퓨터비전
- 웹개발
- 컴퓨터과학
- 파이썬
- 인공지능
- 소프트웨어공학
- 네트워크보안
- 프로그래밍
- 데이터과학
- 컴퓨터공학
- 데이터구조
- 사이버보안
- Yes
- 자료구조
- 알고리즘
- 클라우드컴퓨팅
- I'm Sorry
- 소프트웨어
- 네트워크
- 머신러닝
- 딥러닝
- 데이터베이스
- 프로그래밍언어
- Today
- Total
스택큐힙리스트
스마트 포인터는 무엇이며 언제 사용해야 하나요? 본문
스마트 포인터는 무엇이고 언제 사용해야 할까요?
답변 1
업데이트
이 답변은 다소 오래되어 그 당시에는 Boost 라이브러리에서 제공하는 스마트 포인터가 '좋은' 것으로 여겨졌기 때문에 설명합니다. 그러나 C++11 이후로 표준 라이브러리에서 충분한 스마트 포인터 타입을 제공하므로, std::unique_ptr , std::shared_ptr 및 std::weak_ptr 를 사용하는 것이 좋습니다.
그리고 std::auto_ptr도 있었습니다. 그것은 scoped pointer와 매우 유사했지만, 더욱 위험한 특별한 복사 기능도 가지고 있어서 소유권이 예기치 않게 이전됩니다.
이것은 C++11에서 사용되지 않으며, C++17에서 제거되었으므로 사용하지 마십시오.
std::auto_ptr
std::auto_ptr
// p1 gets set to empty!
p2->DoSomething(); // Works.
p1->DoSomething(); // Oh oh. Hopefully raises some NULL pointer exception.
이전 답변:
스마트 포인터는 가리키는 객체의 수명을 관리하기 위해 '원시'(또는 '단순') C++ 포인터를 래핑하는 클래스입니다. 스마트 포인터 유형은 하나가 아니며 모두가 실용적인 방법으로 원시 포인터를 추상화하려고합니다.
스마트 포인터는 raw 포인터보다 선호되어야 합니다. 포인터를 사용해야 한다고 느끼는 경우 (사용해야 하는지 먼저 검토), 생각하지 못한 객체 삭제 및 메모리 누수와 같은 많은 문제를 완화하기 위해 일반적으로 스마트 포인터를 사용하면 좋습니다.
원시 포인터를 사용하면, 객체가 더 이상 유용하지 않을 때 명시적으로 파괴해야 한다.
// Need to create the object to achieve some goal
MyObject* ptr = new MyObject();
ptr->DoSomething(); // Use the object in some way
delete ptr; // Destroy the object. Done with it.
// Wait, what if DoSomething() raises an exception...?
스마트 포인터는 비교적으로 객체가 파괴될 때 정책을 정의합니다. 여전히 객체를 생성해야하지만, 더 이상 파괴하는 것에 대해 걱정할 필요가 없습니다.
SomeSmartPtr
ptr->DoSomething(); // Use the object in some way.
// Destruction of the object happens, depending
// on the policy the smart pointer class uses.
// Destruction would happen even if DoSomething()
// raises an exception
사용되는 가장 간단한 정책은 스마트 포인터 래퍼 객체의 범위를 포함하며, boost::scoped_ptr 또는 std::unique_ptr에 의해 구현됩니다.
void f()
{
{
std::unique_ptr
ptr->DoSomethingUseful();
} // ptr goes out of scope --
// the MyObject is automatically destroyed.
// ptr->Oops(); // Compile error: ptr not defined
// since it is no longer in scope.
}
std::unique_ptr 인스턴스는 복사할 수 없습니다. 이는 포인터가 여러 번(잘못된 방식으로) 삭제되는 것을 방지합니다. 그러나 호출하는 다른 함수에 대한 참조를 전달할 수는 있습니다.
std::unique_ptr는 객체의 수명을 특정한 코드 블록에 맞추거나 다른 객체의 멤버 데이터로 포함될 경우 해당 다른 객체의 수명을 묶고자 할 때 유용합니다. 해당 객체는 포함하는 코드 블록이 종료되거나 포함하는 객체가 자체적으로 파괴될 때까지 존재합니다.
보다 복잡한 스마트 포인터 정책은 포인터의 참조 수를 계산하는 것을 포함합니다. 이렇게 하면 포인터를 복사할 수 있습니다. 객체에 대한 마지막 참조가 파괴되면 객체가 삭제됩니다. 이 정책은 boost::shared_ptr와 std::shared_ptr에 의해 구현됩니다.
void f()
{
typedef std::shared_ptr
MyObjectPtr p1; // Empty
{
MyObjectPtr p2(new MyObject());
// There is now one reference to the created object
p1 = p2; // Copy the pointer.
// There are now two references to the object.
} // p2 is destroyed, leaving one reference to the object.
} // p1 is destroyed, leaving a reference count of zero.
// The object is deleted.
참조 카운트 포인터는 객체의 수명이 특정 코드 섹션이나 다른 객체와 직접적으로 연결되어 있지 않은 경우 매우 유용합니다.
참조 카운트 포인터의 단점 중 하나는 끈어진 참조(dangling reference)를 만들 수 있는 가능성입니다.
// Create the smart pointer on the heap
MyObjectPtr* pp = new MyObjectPtr(new MyObject())
// Hmm, we forgot to destroy the smart pointer,
// because of that, the object is never destroyed!
다른 가능성은 순환 참조를 만드는 것입니다.
struct Owner {
std::shared_ptr
};
std::shared_ptr
std::shared_ptr
p1->other = p2; // p1 references p2
p2->other = p1; // p2 references p1
// Oops, the reference count of of p1 and p2 never goes to zero!
// The objects are never destroyed!
이 문제를 해결하기 위해 Boost와 C++11은 각각 weak_ptr 를 정의하여 shared_ptr 에 대한 약한 (카운트되지 않는) 참조를 정의했습니다.
답변 2
스마트 포인터는 C++에서 자동 메모리 관리를 수행하는 객체입니다. 이 포인터는 C++의 동적 메모리 할당을 사용하여 객체를 생성하고, 이 객체들을 안전하게 관리합니다. 따라서 스마트 포인터는 객체를 만들어 놓고, 그것들을 삭제하는 작업 등 메모리 관리에 대한 부담을 크게 줄일 수 있습니다.스마트 포인터는 여러 종류가 있으며, 가장 일반적인 것은 unique_ptr, shared_ptr과 weak_ptr입니다. unique_ptr은 특정한 객체를 하나의 소유자 개체만 가질 수 있습니다. 즉, 객체 소멸시 unique_ptr이 소유하는 객체의 메모리를 자동으로 해제합니다. shared_ptr은 객체를 공유할 수 있으며 여러개의 소유자 개체가 있을 경우 마지막 소유자 개체가 소멸될 때 객체가 해제되는 것을 보장합니다. weak_ptr은 shared_ptr 처럼 객체를 공유할 수 있고, 객체의 상태를 확인하지만 객체를 향한 포인터를 만들지 않는 것으로 unique_ptr이나 shared_ptr같은 개체를 만들어내는 생성자가 없습니다.
프로그래머가 자동 메모리 관리를 하지 않으면 메모리 누수 또는 다른 예기치 못한 결과가 발생할 가능성이 있습니다. 스마트 포인터는 이러한 위험을 제거하기 위해 설계되었으며, 메모리 관리를 자동화하는 데 중요한 역할을 합니다. 또한, 스마트 포인터를 사용함으로써 유효한 메모리를 해제하도록 보장하면서도 코드의 성능을 향상시키는 효과도 얻을 수 있습니다.
따라서, C++ 프로그램에서 동적 메모리 할당과 객체 소멸에 대한 위험을 줄이고자 한다면 스마트 포인터를 사용해야 합니다. 제공되는 스마트 포인터 중에서 적절한 것을 선택하여 메모리 할당과 삭제를 고민하지 않아도 되므로 프로그램의 안정성을 크게 향상시키는 데 도움이 됩니다.