etc./StackOverFlow

스마트 포인터란 무엇이며 언제 사용해야 합니까?

청렴결백한 만능 재주꾼 2021. 12. 4. 10:39
반응형

질문자 :Alex Reynolds


스마트 포인터란 무엇이며 언제 사용해야 합니까?



업데이트

이 답변은 다소 오래되었으므로 Boost 라이브러리에서 제공하는 스마트 포인터였던 당시 '좋은' 것이 무엇인지 설명합니다. C++11부터 표준 라이브러리는 충분한 스마트 포인터 유형을 제공하므로 std::unique_ptr , std::shared_ptrstd::weak_ptr 사용을 선호해야 합니다.

std::auto_ptr 도 있었습니다. 그것은 또한 예기치 않게 소유권을 양도하는 "특별한" 위험한 복사 능력이 있다는 점을 제외하고는 범위 포인터와 매우 유사했습니다.
C++11에서 더 이상 사용되지 않으며 C++17에서 제거되었으므로 사용해서는 안 됩니다.

 std::auto_ptr<MyObject> p1 (new MyObject()); std::auto_ptr<MyObject> p2 = p1; // Copy and transfer ownership. // p1 gets set to empty! p2->DoSomething(); // Works. p1->DoSomething(); // Oh oh. Hopefully raises some NULL pointer exception.

오래된 답변

스마트 포인터는 가리키는 개체의 수명을 관리하기 위해 '원시'(또는 '베어') C++ 포인터를 래핑하는 클래스입니다. 단일 스마트 포인터 유형은 없지만 모두 실용적인 방법으로 원시 포인터를 추상화하려고 합니다.

원시 포인터보다 스마트 포인터를 선호해야 합니다. 포인터를 사용할 필요가 있다고 생각되면( 정말로 사용하는 경우 먼저 고려) 일반적으로 스마트 포인터를 사용하고 싶을 것입니다. 스마트 포인터는 주로 객체 삭제를 잊어버리고 메모리 누수가 발생하는 원시 포인터의 많은 문제를 완화할 수 있기 때문입니다.

원시 포인터를 사용하면 프로그래머는 더 이상 유용하지 않을 때 객체를 명시적으로 파괴해야 합니다.

 // 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<MyObject> ptr(new MyObject()); 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<MyObject> ptr(new MyObject()); 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_ptrstd::shared_ptr 의해 구현됩니다.

 void f() { typedef std::shared_ptr<MyObject> MyObjectPtr; // nice short alias 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.

참조 카운트 포인터는 개체의 수명이 훨씬 더 복잡하고 코드의 특정 섹션이나 다른 개체에 직접 연결되어 있지 않을 때 매우 유용합니다.

참조 카운트 포인터에는 한 가지 단점이 있습니다. 댕글링 참조를 생성할 가능성이 있습니다.

 // 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<Owner> other; }; std::shared_ptr<Owner> p1 (new Owner()); std::shared_ptr<Owner> p2 (new Owner()); 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 대한 약한(카운트되지 않은) 참조를 정의했습니다.


Lloyd

다음은 현대 C++(C++11 이상)의 요즈음에 대한 간단한 답변입니다.

  • "스마트 포인터란 무엇입니까?"
    값을 포인터처럼 사용할 수 있지만 자동 메모리 관리의 추가 기능을 제공하는 유형입니다. 스마트 포인터가 더 이상 사용되지 않으면 포인터가 가리키는 메모리가 할당 해제됩니다( Wikipedia 의 자세한 정의 참조).
  • "언제 사용해야 하나요?"
    메모리 조각의 소유권 추적, 할당 또는 할당 해제를 포함하는 코드에서 스마트 포인터를 사용하면 이러한 작업을 명시적으로 수행할 필요가 없는 경우가 많습니다.
  • "그런데 어떤 스마트 포인터를 사용해야 합니까?"
    • 객체에 대한 단일 소유 참조가 존재하는 한 객체를 유지 std::unique_ptr 사용하십시오. 예를 들어, 일부 범위에 들어갈 때 할당되고 범위를 종료할 때 할당 해제되는 메모리에 대한 포인터에 사용합니다.
    • 여러 위치에서 개체를 참조하고 이러한 참조가 모두 사라질 때까지 개체가 할당 해제되는 것을 원하지 않을 때 std::shared_ptr 사용하십시오.
    • std::weak_ptr 사용합니다. 참조를 무시하고 할당 해제해도 됩니다(따라서 역참조를 시도할 때 개체가 사라졌다는 사실만 알 수 있음).
    • boost:: 스마트 포인터나 std::auto_ptr 사용하지 마세요. 필요한 경우 읽을 수 있는 특별한 경우가 아니라면 말이죠.
  • "어이, 어느 걸 쓸지 안 물어봤어!"
    아, 하지만 당신은 정말로 인정하고 싶었습니다.
  • "그럼 일반 포인터는 언제 사용해야 합니까?"
    주로 메모리 소유권을 인식하지 못하는 코드에 있습니다. 이것은 일반적으로 다른 곳에서 포인터를 가져오고 할당하거나 할당 해제하지 않으며 실행보다 오래 지속되는 포인터 복사본을 저장하지 않는 함수에 있습니다.

einpoklum

스마트 포인터 는 자동 메모리 할당 해제, 참조 카운팅 등과 같은 몇 가지 추가 기능이 있는 포인터와 같은 유형입니다.

Smart Pointers - What, Why, What? 페이지에서 간단한 소개를 볼 수 있습니다. .

간단한 스마트 포인터 유형 중 하나는 std::auto_ptr (C++ 표준의 20.4.5장)으로, 범위를 벗어날 때 메모리를 자동으로 할당 해제하고 예외가 throw될 때 단순 포인터 사용보다 더 강력합니다. 덜 유연합니다.

또 다른 편리한 유형은 참조 카운팅을 구현하고 객체에 대한 참조가 남아 있지 않을 때 메모리를 자동으로 할당 해제하는 boost::shared_ptr 이것은 메모리 누수를 피하는 데 도움이 되며 RAII 를 구현하는 데 사용하기 쉽습니다.

이 주제는 David Vandevoorde, Nicolai M. Josuttis의 "C++ Templates: The Complete Guide" 책 20장. 스마트 포인터에서 자세히 다룹니다. 다루는 몇 가지 주제:

  • 예외로부터 보호
  • 홀더(참고, std::auto_ptr 는 이러한 유형의 스마트 포인터를 구현한 것입니다)
  • Resource Acquisition Is Initialization (이것은 C++에서 예외로부터 안전한 리소스 관리에 자주 사용됨)
  • 홀더 제한 사항
  • 참조 카운팅
  • 동시 카운터 액세스
  • 파괴 및 할당 해제

sergtk

Chris, Sergdev 및 Llyod가 제공한 정의는 정확합니다. 하지만 저는 단순한 정의를 선호합니다. 제 삶을 단순하게 유지하기 위해서입니다. 스마트 포인터는 단순히 ->* 연산자를 오버로드하는 클래스입니다. 즉, 객체가 의미상 포인터처럼 보이지만 참조 카운팅, 자동 소멸 등을 포함하여 훨씬 더 멋진 일을 할 수 있다는 것을 의미합니다. shared_ptrauto_ptr 이면 충분하지만 자체적인 작은 특이성 세트가 함께 제공됩니다.


Sridhar Iyer

스마트 포인터는 포인터 자체가 범위를 벗어날 때 포인터가 가리키는 것도 삭제된다는 점을 제외하고는 "char*"와 같은 일반(유형이 지정된) 포인터와 같습니다. "->"를 사용하여 일반 포인터처럼 사용할 수 있지만 데이터에 대한 실제 포인터가 필요한 경우에는 그렇지 않습니다. 이를 위해 "&*ptr"을 사용할 수 있습니다.

다음과 같은 경우에 유용합니다.

  • new로 할당해야 하지만 해당 스택에 있는 것과 동일한 수명을 갖고 싶은 개체. 개체가 스마트 포인터에 할당된 경우 프로그램이 해당 기능/블록을 종료할 때 개체가 삭제됩니다.

  • 클래스의 데이터 멤버, 그래서 객체가 삭제될 때 소유된 모든 데이터도 삭제됩니다. 소멸자에 특별한 코드가 없습니다. (소멸자가 가상인지 확인해야 합니다. 거의 항상 좋은 일입니다) .

다음과 같은 경우 스마트 포인터를 사용하고 싶지 않을 수 있습니다.

  • ... 포인터는 실제로 데이터를 소유해서는 안 됩니다... 즉, 데이터를 사용하고 있지만 참조하는 함수에서 포인터가 유지되기를 원하는 경우입니다.
  • ... 스마트 포인터 자체는 어느 시점에서 파괴되지 않습니다. 절대 소멸되지 않는 메모리(예: 동적으로 할당되지만 명시적으로 삭제되지 않는 객체)에 저장되는 것을 원하지 않습니다.
  • ... 두 개의 스마트 포인터가 동일한 데이터를 가리킬 수 있습니다. (그러나 이를 처리하는 더 똑똑한 포인터가 있습니다... 이를 참조 카운팅 이라고 합니다.)

또한보십시오:


markets

스마트 포인터는 포인터처럼 작동하지만 추가로 생성, 파괴, 복사, 이동 및 역참조에 대한 제어를 제공하는 개체입니다.

자신의 스마트 포인터를 구현할 수 있지만 많은 라이브러리는 각각 장단점이 있는 스마트 포인터 구현도 제공합니다.

예를 들어 Boost 는 다음과 같은 스마트 포인터 구현을 제공합니다.

  • shared_ptr<T> 는 참조 카운트를 사용하여 개체가 더 이상 필요하지 않은 시점을 결정하는 T 대한 포인터입니다.
  • scoped_ptr<T> 는 범위를 벗어나면 자동으로 삭제되는 포인터입니다. 할당이 불가능합니다.
  • intrusive_ptr<T> 는 또 다른 참조 카운팅 포인터입니다. shared_ptr 보다 더 나은 성능을 제공하지만 고유한 참조 카운팅 메커니즘을 제공하려면 유형 T
  • weak_ptr<T> 는 순환 참조를 피하기 위해 shared_ptr 과 함께 작동하는 약한 포인터입니다.
  • shared_array<T>shared_ptr 과 비슷하지만 T 배열의 경우입니다.
  • scoped_array<T>scoped_ptr 과 비슷하지만 T 배열의 경우입니다.

이것들은 각각에 대한 하나의 선형 설명이며 필요에 따라 사용할 수 있습니다. 자세한 내용과 예제는 Boost 문서를 참조하세요.

또한 C++ 표준 라이브러리는 세 가지 스마트 포인터를 제공합니다. 고유 소유권의 경우 std::unique_ptr , 공유 소유권의 std::shared_ptr std::weak_ptr . std::auto_ptr 은 C++03에 있었지만 지금은 더 이상 사용되지 않습니다.


Saqlain

대부분의 스마트 포인터는 포인터 대상 개체의 처리를 처리합니다. 더 이상 수동으로 개체를 처리할 필요가 없기 때문에 매우 편리합니다.

가장 일반적으로 사용되는 스마트 포인터는 std::tr1::shared_ptr (또는 boost::shared_ptr ) 및 덜 일반적으로 std::auto_ptr 입니다. shared_ptr 정기적으로 사용하는 것이 좋습니다.

shared_ptr 은 매우 다재다능하며 개체를 "DLL 경계를 넘어 전달"해야 하는 경우를 포함하여 매우 다양한 폐기 시나리오를 처리합니다(코드와 DLL 간에 libc


Chris Jester-Young

다음은 유사한 답변에 대한 링크입니다. http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

스마트 포인터는 일반 포인터처럼 작동하고 모양과 느낌이 비슷하지만 더 많은 기능을 제공하는 개체입니다. C++에서 스마트 포인터는 포인터를 캡슐화하고 표준 포인터 연산자를 재정의하는 템플릿 클래스로 구현됩니다. 일반 포인터에 비해 많은 장점이 있습니다. null 포인터 또는 힙 개체에 대한 포인터로 초기화되는 것이 보장됩니다. 널 포인터를 통한 간접 참조가 확인됩니다. 삭제할 필요가 없습니다. 객체에 대한 마지막 포인터가 사라지면 객체가 자동으로 해제됩니다. 이러한 스마트 포인터의 중요한 문제 중 하나는 일반 포인터와 달리 상속을 존중하지 않는다는 것입니다. 스마트 포인터는 다형성 코드에 적합하지 않습니다. 다음은 스마트 포인터 구현에 대한 예입니다.

예시:

 template <class X> class smart_pointer { public: smart_pointer(); // makes a null pointer smart_pointer(const X& x) // makes pointer to copy of x X& operator *( ); const X& operator*( ) const; X* operator->() const; smart_pointer(const smart_pointer <X> &); const smart_pointer <X> & operator =(const smart_pointer<X>&); ~smart_pointer(); private: //... };

이 클래스는 X 유형의 개체에 대한 스마트 포인터를 구현합니다. 개체 자체는 힙에 있습니다. 사용 방법은 다음과 같습니다.

 smart_pointer <employee> p= employee("Harris",1333);

다른 오버로드된 연산자와 마찬가지로 p는 일반 포인터처럼 동작합니다.

 cout<<*p; p->raise_salary(0.5);

Santosh

http://en.wikipedia.org/wiki/Smart_pointer

컴퓨터 과학에서 스마트 포인터는 포인터를 시뮬레이션하는 동시에 자동 가비지 수집 또는 경계 검사와 같은 추가 기능을 제공하는 추상 데이터 유형입니다. 이러한 추가 기능은 효율성을 유지하면서 포인터의 오용으로 인한 버그를 줄이기 위한 것입니다. 스마트 포인터는 일반적으로 메모리 관리 목적으로 가리키는 개체를 추적합니다. 포인터의 오용은 버그의 주요 원인입니다. 포인터를 사용하여 작성된 프로그램에서 수행해야 하는 일정한 할당, 할당 해제 및 참조로 인해 일부 메모리 누수가 발생할 가능성이 매우 높습니다. 스마트 포인터는 리소스 할당 해제를 자동으로 하여 메모리 누수를 방지하려고 합니다. 예를 들어 범위를 벗어나서 개체에 대한 포인터(또는 일련의 포인터 중 마지막 포인터)가 파괴되면 해당 개체도 파괴됩니다.


Jorge Ferreira

이 튜토리얼에서는 T를 클래스로 설정합니다. C++의 포인터는 3가지 유형으로 나눌 수 있습니다.

1) 원시 포인터 :

 T a; T * _ptr = &a;

그들은 메모리의 한 위치에 대한 메모리 주소를 보유합니다. 프로그램이 복잡해지면 추적하기 어려워지므로 주의해서 사용하십시오.

const 데이터 또는 주소가 있는 포인터 { 역방향 읽기 }

 T a ; const T * ptr1 = &a ; T const * ptr1 = &a ;

const인 데이터 유형 T에 대한 포인터입니다. 포인터를 사용하여 데이터 유형을 변경할 수 없음을 의미합니다. 즉 *ptr1 = 19 ; 작동하지 않을 것이다. 그러나 포인터를 이동할 수 있습니다. 즉, ptr1++ , ptr1-- ; 등이 작동합니다. 뒤로 읽기: const인 T 유형에 대한 포인터

 T * const ptr2 ;

데이터 형식 T 에 대한 const 포인터입니다. 포인터를 이동할 수는 없지만 포인터가 가리키는 값을 변경할 수 있음을 의미합니다. 즉 *ptr2 = 19 는 작동하지만 ptr2++ ; ptr2-- 등은 작동하지 않습니다. 거꾸로 읽기 : T 유형에 대한 const 포인터

 const T * const ptr3 ;

const 데이터 형식 T 에 대한 const 포인터입니다. 즉, 포인터를 이동할 수 없으며 데이터 유형 포인터를 포인터로 변경할 수 없습니다. 즉 . ptr3-- ; ptr3++ ; *ptr3 = 19; 작동하지 않을 것이다

3) 스마트 포인터 : { #include <memory> }

공유 포인터 :

 T a ; //shared_ptr<T> shptr(new T) ; not recommended but works shared_ptr<T> shptr = make_shared<T>(); // faster + exception safe std::cout << shptr.use_count() ; // 1 // gives the number of " things " pointing to it. T * temp = shptr.get(); // gives a pointer to object // shared_pointer used like a regular pointer to call member functions shptr->memFn(); (*shptr).memFn(); // shptr.reset() ; // frees the object pointed to be the ptr shptr = nullptr ; // frees the object shptr = make_shared<T>() ; // frees the original object and points to new object

포인터가 가리키는 객체를 가리키는 "것"의 수를 추적하기 위해 참조 카운팅을 사용하여 구현되었습니다. 이 수가 0이 되면 객체가 자동으로 삭제됩니다. 즉, 객체를 가리키는 모든 share_ptr이 범위를 벗어날 때 objected가 삭제됩니다. 이것은 new를 사용하여 할당한 객체를 삭제해야 하는 두통을 없애줍니다.

Weak Pointer: Shared Pointer를 사용할 때 발생하는 순환 참조를 처리하는 데 도움이 됩니다. 두 개의 공유 포인터가 가리키는 두 개의 객체가 있고 서로를 가리키는 내부 공유 포인터가 있는 경우 순환 참조가 있고 객체는 그렇지 않습니다. 공유 포인터가 범위를 벗어나면 삭제됩니다. 이를 해결하려면 내부 멤버를 shared_ptr에서 weak_ptr로 변경합니다. 참고: 약한 포인터가 가리키는 요소에 액세스하려면 lock()을 사용하면 weak_ptr이 반환됩니다.

 T a ; shared_ptr<T> shr = make_shared<T>() ; weak_ptr<T> wk = shr ; // initialize a weak_ptr from a shared_ptr wk.lock()->memFn() ; // use lock to get a shared_ptr // ^^^ Can lead to exception if the shared ptr has gone out of scope if(!wk.expired()) wk.lock()->memFn() ; // Check if shared ptr has gone out of scope before access

참조: std::weak_ptr은 언제 유용합니까?

Unique Pointer : 독점 소유권을 가진 경량 스마트 포인터. 포인터 간에 개체를 공유하지 않고 포인터가 고유한 개체를 가리킬 때 사용합니다.

 unique_ptr<T> uptr(new T); uptr->memFn(); //T * ptr = uptr.release(); // uptr becomes null and object is pointed to by ptr uptr.reset() ; // deletes the object pointed to by uptr

고유한 ptr이 가리키는 객체를 변경하려면 이동 의미 체계를 사용하십시오.

 unique_ptr<T> uptr1(new T); unique_ptr<T> uptr2(new T); uptr2 = std::move(uptr1); // object pointed by uptr2 is deleted and // object pointed by uptr1 is pointed to by uptr2 // uptr1 becomes null

참조: 그것들은 본질적으로 const 포인터, 즉 const이고 더 나은 구문으로 이동할 수 없는 포인터로 간주될 수 있습니다.

참조: C++에서 포인터 변수와 참조 변수의 차이점은 무엇입니까?

 r-value reference : reference to a temporary object l-value reference : reference to an object whose address can be obtained const reference : reference to a data type which is const and cannot be modified

참조 : https://www.youtube.com/channel/UCEOGtxYTB6vo6MQ-WQ9W_nQ 이 질문을 지적해 준 Andre에게 감사합니다.


nnrales

스마트 포인터는 일반 포인터의 래퍼인 클래스입니다. 일반 포인터와 달리 스마트 포인트의 라이프 서클은 참조 횟수(스마트 포인터 개체가 할당된 횟수)를 기반으로 합니다. 따라서 스마트 포인터가 다른 포인터에 할당될 때마다 내부 참조 카운트에 더하기가 추가됩니다. 그리고 개체가 범위를 벗어날 때마다 참조 횟수에서 빼기를 뺍니다.

자동 포인터는 비슷해 보이지만 스마트 포인터와 완전히 다릅니다. 자동 포인터 객체가 변수 범위를 벗어날 때마다 리소스를 할당 해제하는 편리한 클래스입니다. 어느 정도까지는 포인터(동적으로 할당된 메모리에 대한)가 스택 변수(컴파일 시간에 정적으로 할당됨)와 유사하게 작동합니다.


Trombe

스마트 포인터란?

긴 버전, 원칙적으로:

https://web.stanford.edu/class/archive/cs/cs106l/cs106l.1192/lectures/lecture15/15_RAII.pdf

현대적인 C++ 관용구:

 RAII: Resource Acquisition Is Initialization. ● When you initialize an object, it should already have acquired any resources it needs (in the constructor). ● When an object goes out of scope, it should release every resource it is using (using the destructor).

핵심:

 ● There should never be a half-ready or half-dead object. ● When an object is created, it should be in a ready state. ● When an object goes out of scope, it should release its resources. ● The user shouldn't have to do anything more.

원시 포인터가 RAII를 위반함 : 포인터가 범위를 벗어날 때 사용자가 수동으로 삭제해야 합니다.

RAII 솔루션은 다음과 같습니다.

 Have a smart pointer class: ● Allocates the memory when initialized ● Frees the memory when destructor is called ● Allows access to underlying pointer

스마트 포인터에 복사 및 공유가 필요한 경우 shared_ptr을 사용하십시오.

 ● use another memory to store Reference counting and shared. ● increment when copy, decrement when destructor. ● delete memory when Reference counting is 0. also delete memory that store Reference counting.

원시 포인터를 소유하지 않는 스마트 포인터의 경우 weak_ptr을 사용하십시오.

 ● not change Reference counting.

shared_ptr 사용법:

 correct way: std::shared_ptr<T> t1 = std::make_shared<T>(TArgs); std::shared_ptr<T> t2 = std::shared_ptr<T>(new T(Targs)); wrong way: T* pt = new T(TArgs); // never exposure the raw pointer shared_ptr<T> t1 = shared_ptr<T>(pt); shared_ptr<T> t2 = shared_ptr<T>(pt);

항상 원시 포인터를 사용하지 마십시오.

원시 포인터를 사용해야 하는 시나리오의 경우:

https://stackoverflow.com/a/19432062/2482283

nullptr이 아닌 원시 포인터의 경우 대신 참조를 사용하십시오.

 not use T* use T&

nullptr일 수 있는 선택적 참조의 경우 원시 포인터를 사용합니다. 이는 다음을 의미합니다.

 T* pt; is optional reference and maybe nullptr. Not own the raw pointer, Raw pointer is managed by some one else. I only know that the caller is sure it is not released now.

lbsweek

스마트 포인터는 메모리 할당 해제, 리소스 공유 및 전송에 대해 걱정할 필요가 없는 포인터입니다.

Java에서 할당이 작동하는 것과 유사한 방식으로 이러한 포인터를 매우 잘 사용할 수 있습니다. Java에서는 Garbage Collector가 트릭을 수행하지만 Smart Pointers에서는 트릭을 Destructors가 수행합니다.


Deepak K Gupta

기존 답변은 좋지만 스마트 포인터가 해결하려는 문제에 대한 (완전한) 답변이 아닐 때 수행할 작업은 다루지 않습니다.

무엇보다도 스마트 포인터를 사용하는 것이 (다른 답변에서 잘 설명됨) 추상 클래스를 함수 반환 유형으로 사용하는 방법에 대한 가능한 솔루션입니다. 이 질문의 중복으로 표시되었습니다. 그러나 C++에서 추상(또는 실제로 모든) 기본 클래스를 반환 유형으로 지정하고 싶은지 묻는 첫 번째 질문은 "무슨 뜻인가요?"입니다. 부스트 포인터 컨테이너 라이브러리 문서에서 C++의 관용적 객체 지향 프로그래밍(및 이것이 다른 언어와 어떻게 다른지)에 대한 좋은 토론(추가 참조 포함)이 있습니다. 요약하면 C++에서는 소유권에 대해 생각해야 합니다. 어떤 스마트 포인터가 도움이 되지만 유일한 솔루션은 아니며 항상 완전한 솔루션(다형성 사본을 제공하지 않음)이 아니며 항상 인터페이스에 노출하려는 솔루션이 아닙니다(함수 반환이 끔찍하게 들립니다. 인터페이스와 매우 유사함). 예를 들어 참조를 반환하는 것으로 충분할 수 있습니다. 그러나 이러한 모든 경우(스마트 포인터, 포인터 컨테이너 또는 단순히 참조 반환)에서 반환을 에서 참조 형식으로 변경했습니다. 복사가 정말 필요한 경우 상용구 "관용구"를 더 추가하거나 C++의 관용적(또는 기타) OOP를 넘어 Adobe Poly 또는 Boost.TypeErasure 와 같은 라이브러리를 사용하여 보다 일반적인 다형성으로 이동해야 할 수 있습니다.


da77a

출처 : http:www.stackoverflow.com/questions/106508/what-is-a-smart-pointer-and-when-should-i-use-one

반응형