묻고 답해요
145만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결홍정모의 따라하며 배우는 C++
소멸자에서 Exception Error가 발생하는데 원인을 잘 모르겠습니다.
안녕하세요, 9.12 이니셜라이저 리스트 강의 수강중에 동일한 코드 빌드시 그림과 같이 소멸자에서 에러가 납니다. 원인이 무엇인지, 제가 어떤 부분에 대한 이해가 부족한 것인지 짚어주시면 감사하겠습니다.
-
해결됨홍정모의 따라하며 배우는 C++
수업시간 코드인데 결과값이 왜 이렇게 나오는지 궁금합니다.
#include <iostream> #include "autoptr.h" //#include "autoptr2.h" #include "resource.h" #include "Timer.h" AutoPtr<Resource> generateResource() // AutoPtr<Resource> 타입을 리턴하는 함수 { // 10000000 의 length를 가진 Resource타입의 멤버를 가지는 AutoPtr 객체 생성 AutoPtr<Resource> res(new Resource(10000000)); return res; } int main() { using namespace std; streambuf* orig_buf = cout.rdbuf(); // cout.rdbuf(NULL); 화면에 출력되는 메세지들 끄기. 시간 어마어마하게 걸릴테니까 😎 Timer timer; { AutoPtr<Resource> main_res; main_res = generateResource(); // ⭐ generateResource() 리턴값은 R-value } cout.rdbuf(orig_buf); //cout << timer.elapsed() << endl; timer.elapsed();//실행시간 재서 출력 }메인.cpp#pragma once #include <iostream> using namespace std; template<typename T> class AutoPtr { public: T* m_ptr; public: AutoPtr(T* ptr = nullptr) :m_ptr(ptr) { cout << "AutoPtr default constructor" << endl; } ~AutoPtr() { cout << "AutoPtr destructor" << endl; if (m_ptr != nullptr) delete m_ptr; } AutoPtr(const AutoPtr& a) // 💎복사 생성자💎 { cout << "AutoPtr copy constructor" << endl; // deep copy m_ptr = new T; // T가 Resource 타입으로 들어오면 m_ptr은 Resource 타입의 포인터 *m_ptr = *a.m_ptr; // ⭐Resource의 '대입 연산자 오버로딩 호출 , deep copy } AutoPtr& operator = (const AutoPtr& a) //L-value 레퍼런스 , 💎대입 연산자 오버로딩💎 { cout << "AutoPtr copy assignment" << endl; if (&a == this) return *this; if (m_ptr != nullptr) delete m_ptr; // deep copy m_ptr = new T; // 새로운 빈 공간 할당 받기. T가 Resource 타입으로 들어오면 m_ptr은 Resource 타입의 포인터 *m_ptr = *a.m_ptr; // ⭐Resource의 '대입 연산자 오버로딩' 호출 , deep copy return *this; } T& operator *() const { return *m_ptr; } T* operator ->() const { return m_ptr; } bool inNull() const { return m_ptr == nullptr; } };AutoPtr 헤더파일#pragma once #include <iostream> using namespace std; class Resource { public: int* m_data = nullptr; unsigned m_length = 0; public: Resource() // 기본 생성자 { cout << "Resource constructed" << endl; } Resource(unsigned length) // 일반 매개변수 1개 생성자 { cout << "Resource length constructed" << endl; this->m_data = new int[length]; this->m_length = length; } Resource(const Resource& res) // 💎복사 생성자💎 { cout << "Resource copy constructed" << endl; Resource(res.m_length); for (unsigned i = 0; i < m_length; ++i) // 내용물을 전부 깊은 복사 (시간이 꽤 걸림) m_data[i] = res.m_data[i]; } ~Resource() // 소멸자 { cout << "Resource destroyed" << endl; } Resource& operator = (Resource& res) // 💎대입 연산자 오버로딩💎 { cout << "Resource copy assignment" << endl; if (&res == this) return *this; // 대입하려는게 자기 자신이면 아무것도 안함 if (this->m_data != nullptr) delete[] m_data; // 1. 내 자신의 m_data 비워주기 m_length = res.m_length; // 2. 대입으로 넘겨받은 res의 length 로 내 length 갱신 m_data = new int[m_length]; // 3. 비워진 내 자신의 m_data에 새로운 공간 할당받기 for (unsigned i = 0; i < m_length; ++i) // 4. m_data내용물 넣기. m_data[i] = res.m_data[i]; // 대입으로 넘겨받은 res의 m_data 내용물들을 **내 m_data**에 깊은 복사 return *this; } };Resource헤더파일 결과값이AutoPtr default constructorResource length constructedAutoPtr default constructorAutoPtr copy assignmentResource constructedResource copy assignmentAutoPtr destructorResource destroyedAutoPtr destructorResource destroyed 이렇게 나왔습니다.여기서 궁금한점은 소멸자 출력문구 순서인데요디버깅을 해봤는데Timer timer;{AutoPtr<Resource> main_res;main_res = generateResource();}이 지역범위를 벗어나고 소멸자 호출을 시작하는데 정확히 main_res = generateResource(); 이부분에서AutoPtr destructorResource destroyedAutoPtr destructorResource destroyed이 4번의 소멸자가 호출됩니다. 그에 대한 설명을 나름 추리해봤는데 제 설명이 맞는지 확인해주시고 혹시 틀렸다면 정확히 어떤점에서 틀렸고 어떠한 근거로 저 소멸자호출문구가 출력 되는건지 알려주실 수 있나요? 저의 설명==================================AutoPtr destructor >>> generateResource() 함수의 리턴 값인 res를 블럭이 끝나면서 소멸자로 할당값을 해제해주는 과정에서 소멸자 호출 Resource destroyed >>> 소멸자 호출 문구 출력 이후 if (m_ptr != nullptr) delete m_ptr; 구문 실행과정에서 m_ptr이 resource타입이니까 삭제시에 resource 소멸자 호출 AutoPtr destructor >>> main_res 역시 해제하기 위해 autoptr의 소멸자 호출 Resource destroyed >>>소멸자 호출 문구 출력 이후 if (m_ptr != nullptr) delete m_ptr; 구문 실행과정에서m_ptr이 resource타입이니까 삭제시에 resource 소멸자 호출
-
미해결홍정모의 따라하며 배우는 C++
15.1 9분50초
AutoPtr<Resource> res(new Resource);여기서 res도 동적할당으로 생성이 된것인데res의 클래스 템플릿인 AutoPtr에서 소멸자가 호출이 되면 거기서 Resource로 만들어진 부분을 delete하는 것이 들어가 있어서 지워지는 것까지는 이해가 되는데res도 동적할당을 받았을텐데 어떻게 delete res를 하지 않았는데 AutoPtr의 소멸자가 호출이 되는건가요?????
-
미해결프로그래밍 시작하기 : 파이썬 입문 (Inflearn Original)
소멸자에서 전체 인스턴스에 활당이 안되는것같습니다.
- class Warehouse: # 클래스 변수 stock_num = 0 # 재고 def __init__(self, name): # 인스턴스 변수 Warehouse.stock_num += 2 # 클래스명으로 만든 변수는 모든 인스턴스에 활당 self.name = name #self로 만든 변수는 각각의 인스턴스에 2당 self.stock_num+=100 print(self.name,self.stock_num) def __del__(self): Warehouse.stock_num -= 2 self.stock_num-=100 print(self.name,self.stock_num) user1 = Warehouse('Lee') # Lee 102 user2 = Warehouse('Cho') # Cho 104 del user1 # Lee 2 -> 102-100 del user2 # Lee 0 이나와야 하는데 4가 나옴 ->104-100 소멸자에서 Warehose.stock_num 이 안먹힌거 같은데 왜그런거죠?
-
미해결프로그래밍 시작하기 : 파이썬 입문 (Inflearn Original)
소멸자의 호출에 관한 질문입니다
소멸자는 '객체가 소멸할 때 자동으로 호출되는 함수'라고 설명하셨는데 이게 정확히 어떤 원리인지 잘 모르겠습니다 class IceCream: def __init__(self, name, price): self.name = name self.price = price print(self.name + '의 가격은' + str(self.price) + '원 입니다') def __del__(self): print(self.name + '객체가 소멸합니다') obj = IceCream('월드콘', 1000) 위와 같이 코드를 작성해 보았는데요, 객체만 생성하였는데도 이를 실행하니까 __del__메소드의 내용까지 모두 실행되는 것을 확인할 수 있었습니다. del obj 와 같은 코드를 입력해야 __del__메소드가 실행되는 것이 아닌가요?? 뭐가 문제인지 궁금합니다