일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 강화학습
- pandas
- 소수
- align-items
- Prefix Sums
- 수학
- c
- Flexbox
- stl
- dataframe
- Javascript
- 상태
- margin
- 에라토스테네스의 체
- Codility
- spring
- 통신사할인
- Photoshop
- c++
- CSS
- skt membership
- SK바이오사이언스
- 포토샵
- Gap
- 확률
- Design Pattern
- grid
- 알고리즘
- 백준
- series
Archives
- Today
- Total
sliver__
[Mastering C++ Programming] - auto ptr 본문
728x90
- auto_ptr 스마트 포인터는 raw pointer를 가져와 래핑하고 auto_ptr 개체가 범위를 벗어날 때마다 원시 포인터가 가리키는 메모리가 다시 해제되도록 합니다.
- 언제든지 auto_ptr 스마트 포인터 하나만 개체를 가리킬 수 있습니다.
- 따라서 하나의 auto_ptr 포인터가 다른 auto_ptr 포인터에 할당될 때마다 소유권은 할당을 받은 auto_ptr 인스턴스로 이전됩니다.
- auto_ptr 스마트 포인터가 복사될 때도 마찬가지입니다.
#include <iostream>
#include <string>
#include <memory>
#include <sstream>
using namespace std;
class MyClass {
private:
static int count;
string name;
public:
MyClass() {
ostringstream stringStream(ostringstream::ate);
stringStream << "Object";
stringStream << ++count;
name = stringStream.str();
cout << "\nMyClass Default constructor - " << name << endl;
}
~MyClass() {
cout << "\nMyClass destructor - " << name << endl;
}
MyClass ( const MyClass &objectBeingCopied ) {
cout << "\nMyClass copy constructor" << endl;
}
MyClass& operator = ( const MyClass &objectBeingAssigned ) {
cout << "\nMyClass assignment operator" << endl;
}
void sayHello( ) {
cout << "Hello from MyClass " << name << endl;
}
};
int MyClass::count = 0;
int main ( ) {
auto_ptr<MyClass> ptr1( new MyClass() );
auto_ptr<MyClass> ptr2( new MyClass() );
return 0;
}
- 결과는 아래와 같다.
g++ main.cpp -std=c++17
main.cpp: In function ‘int main()’:
main.cpp:40:2: warning: ‘template<class> class std::auto_ptr’ is deprecated [-Wdeprecated-declarations]
auto_ptr<MyClass> ptr1( new MyClass() );
In file included from /usr/include/c++/6/memory:81:0,
from main.cpp:3:
/usr/include/c++/6/bits/unique_ptr.h:49:28: note: declared here
template<typename> class auto_ptr;
main.cpp:41:2: warning: ‘template<class> class std::auto_ptr’ is deprecated [-Wdeprecated-declarations]
auto_ptr<MyClass> ptr2( new MyClass() );
In file included from /usr/include/c++/6/memory:81:0,
from main.cpp:3:
/usr/include/c++/6/bits/unique_ptr.h:49:28: note: declared here
template<typename> class auto_ptr;
g++ main.cpp -Wno-deprecated
./a.out
MyClass Default constructor - Object1
MyClass Default constructor - Object2
MyClass destructor - Object2
MyClass destructor - Object1
- 하지만 auto_ptr은 소유권 이전 문제로 사용하지 않는다.
- 예제는 아래와 같다.
int main ( ) {
auto_ptr<MyClass> ptr1( new MyClass() );
auto_ptr<MyClass> ptr2( new MyClass() );
ptr1->sayHello();
ptr2->sayHello();
//At this point the below stuffs happen
//1. ptr2 smart pointer has given up ownership of MyClass Object 2
//2. MyClass Object 2 will be destructed as ptr2 has given up its
// ownership on Object 2
//3. Ownership of Object 1 will be transferred to ptr2
ptr2 = ptr1;
//The line below if uncommented will result in core dump as ptr1
//has given up its ownership on Object 1 and the ownership of
//Object 1 is transferred to ptr2.
// ptr1->sayHello();
ptr2->sayHello();
return 0;
}
- auto_ptr ptr1 개체가 포인터라고 믿게 만들지만 실제로 ptr1 및 ptr2는 로컬 변수로 스택에 생성된 auto_ptr 개체일 뿐입니다.
- auto_ptr 클래스는 -> 포인터 연산자와 * 역참조 연산자를 오버로드했기 때문에 포인터처럼 보입니다.
- 사실, MyClass에 의해 노출된 모든 메서드는 -> 포인터 연산자를 통해서만 액세스할 수 있는 반면, 모든 auto_ptr 메서드는 스택 개체에 정기적으로 액세스하는 것처럼 액세스할 수 있습니다.
ptr2 = ptr1;
- 앞의 코드는 단순한 대입문인 것처럼 보이지만 auto_ptr 내에서 많은 활동을 트리거합니다.
- 앞의 할당문으로 인해 다음 활동이 발생합니다.
- ptr2 스마트 포인터는 MyClass 개체 2의 소유권을 포기합니다.
- MyClass 객체 2는 ptr2가 객체 2의 소유권을 포기했기 때문에 소멸됩니다.
- 객체 1의 소유권은 ptr2로 이전됩니다.
- 이 시점에서 ptr1은 객체 1을 가리키지 않으며 객체 1이 사용하는 메모리를 관리할 책임도 없습니다.
// ptr1->sayHello();
- ptr1 스마트 포인터가 객체 1의 소유권을 해제했기 때문에 sayHello() 메서드에 액세스를 시도하는 것은 불가능하다.
- 이는 실제로 ptr1이 더 이상 객체 1을 가리키지 않고 객체 1을 ptr2가 소유하기 때문입니다.
- ptr2가 범위를 벗어날 때 객체 1에서 사용하는 메모리를 해제하는 것은 ptr2 스마트 포인터의 책임입니다.
- 이전 코드의 주석을 제거하면 코어 덤프가 발생합니다.
ptr2->sayHello();
return 0;
- 방금 본 return 문은 main() 함수에서 스택 rewinding 프로세스를 시작합니다.
- 이렇게 하면 결국 ptr2의 소멸자가 호출되고 객체 1이 사용하는 메모리가 할당 해제됩니다.
- 모든 것이 자동으로 발생한다는 것입니다.
- auto_ptr 스마트 포인터는 당면한 문제에 집중하는 동안 보이지 않는 곳에서 열심히 작동합니다.
- 그러나 다음과 같은 이유로 인해 auto_ptr은 C++11부터 더 이상 사용되지 않습니다.
- auto_ptr 개체는 STL 컨테이너에 저장할 수 없습니다.
- auto_ptr 복사 생성자는 원래 소스, 즉 auto_ptr에서 소유권을 제거합니다.
- auto_ptr 복사 할당 연산자는 원래 소스인 auto_ptr에서 소유권을 제거합니다.
- auto_ptr 복사 생성자 및 할당 연산자가 오른쪽 개체에서 소스 개체의 소유권을 제거하고 소유권을 왼쪽 개체에 할당하므로 복사 생성자 및 할당 연산자의 원래 의도는 auto_ptr에 의해 위반됩니다.
728x90
'CS > C++' 카테고리의 다른 글
[Mastering C++ Programming] - shared_ptr (0) | 2022.12.07 |
---|---|
[Mastering C++ Programming] - unique_ptr (0) | 2022.12.07 |
[Mastering C++ Programming] - Smart Pointer (0) | 2022.12.07 |
[Mastering C++ Programming] - Issues with raw pointers (0) | 2022.12.07 |
[Mastering C++ Programming] - Memory Management (0) | 2022.12.07 |
Comments