• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    해결됨

파괴자 질문드립니다.

21.02.23 15:55 작성 조회수 171

3

'클래스 생성자와 파괴자' 강의 5:58 부분에서

Coding 클래스 생성자를 temp에 대입하였는데,

기존에 있던 Panda클래스가 아닌,

Coding클래스가 소멸한다고 하고 뒤에 Coding 클래스가 출력되는지 궁금합니다.

답변 3

·

답변을 작성해보세요.

6

조금 긴 답변이 될 것 같습니다.

먼저 클래스 소멸에 관하여 다시 한 번만 짚고 넘어가겠습니다.

제 강의에서는 memory 챕터를 설명하지 않아서 관련된 내용에 관한 링크를 공유해드립니다.

(https://stackoverflow.com/questions/18054636/c-destructors-when-and-where-if-ever)

클래스는 세 가지 유형으로 생성할 수 있는데,

각 유형마다 파괴자가 호출되는 방식이 상이합니다.

첫 번째로 자동 할당입니다.

int main()
{
  A a; // A는 클래스 이름입니다.
  //...
}

이러한 방식에서 클래스는 자동 메모리에 위치해 있습니다.

컴파일러가 클래스를 사용하지 않는 시점을 계산하여 자동으로 파괴자를 호출합니다.

저희 예제가 현재 이러한 방식입니다.

두 번째로 동적 할당입니다.

int main()
{
  A* a = new A;
  delete a;    //destructor called
}

이 경우에 클래스 개체는 동적 메모리에 위치하고 있습니다.

따라서 클래스를 파괴시키기 위해서는 delete를 이용해 파괴자를 호출하여야만 합니다.

세 번째로 정적 할당입니다.

A a; //namespace scope

int main()
{
}

이 경우에서 클래스는 static 메모리에 위치하고 있습니다.

그리고 다시 프로그램이 종료될 때 자동으로 파괴자가 호출됩니다.

다시 저희의 예제로 돌아와서,

저희는 현재 자동 할당의 방식으로 클래스를 선언하였습니다.

따라서 컴파일러가 클래스가 더 이상 사용하지 않는 시점이 오면,

자동으로 파괴자를 호출하여 클래스를 파괴합니다.

제가 올려드린 코드를 실행해 보시면 아래와 같은 실행 결과를 얻으실 수 있으실 겁니다.

생성자가 4번 호출되었고, 파괴자 역시 따로 호출해주지 않았음에도 4번 호출되었습니다.

코드 상에서 "A"라는 이름을 가진 A객체는 생성자에 의해 "D"라는 이름으로  새로 선언되었습니다.

이 시점에서 "A"라는 이름을 가진 A객체는 코드가 진행되면서 더 이상 사용할 일이 없기에, 소멸됩니다.

소멸되는 시점에서 이미 이름이 "D"이기 때문에,

콘솔창에서 "D클래스가 소멸되었습니다." 라고 명시된 것을 확인할 수 있습니다.

그 이후 "D 객체입니다"가 출력된 것은

이제 "D"라는 이름을 가진 A객체의 이해 show함수가 사용되었기 때문입니다.

이후 코드를 실행함에 따라 프로그램이 종료될 때가 되면,

A객체를 포함하여 선언되었던 모든 클래스 객체가 사용되지 않는 것을 컴파일러가 압니다.

따라서 순차적으로 파괴자가 호출된 것입니다.

(파괴자의 호출 순서는 컴파일러의 환경에 따라 다를 수 있습니다.)

그래서 질문해주신 내용을 다시 살펴보면

기존에 있던 Panda 클래스가 소멸되고 나서, 새로 대입한 Coding 클래스가 출력된 것입니다.

하지만 콘솔창에서 Coding클래스가 소멸되었다고 출력되기에 충분히 헷갈릴만한 부분인 것 같습니다.

(파괴자는 파괴할 당시 name을 출력하는 데, 파괴자가 호출되었을 때 이미 name의 값은 바뀌었기 때문입니다!)

혹시 이해가 되셨을까요?

주원님의 프로필

주원

2022.02.01

돈이 되는것도 아닌데 이렇게 답변달아주시고 정말 감사합니다

1

whdtmd96님의 프로필

whdtmd96

질문자

2021.02.23

친절한 설명 너무 감사합니다. 乃

덕분에 잘 이해했습니다!!

0

답변에 사용될 코드입니다.

Stock.h

#ifndef STOCK
#define STOCK
#include <iostream>


using namespace std;

class Stock
{
private:
	string name;

public: 
	void show();
	Stock(string);
	Stock();
	~Stock();
};
#endif // !STOCK

func.cpp

#include "Stock.h"


void Stock::show() {
	cout << name << "객체입니다.\n";
}

Stock::Stock(string co) {
	name = co;
	cout << co << "객체가 생성되었습니다.\n";
}

Stock::Stock() {
	cout << "객체가 생성되었습니다.\n";
}


Stock::~Stock()
{
	cout << name << "클래스가 소멸되었습니다. \n";
}

main.cpp

#include <iostream>
#include "Stock.h"

int main() {

	Stock A("A");
	A.show();
	Stock B("B");
	Stock C("C");

	A = Stock("D");
	A.show();

	return 0;

}