C++에서 명시 적으로 소멸자 호출

Jinku Hu 2023년10월12일
C++에서 명시 적으로 소멸자 호출

이 기사에서는 C++에서 명시 적으로 소멸자를 호출하는 방법에 대한 몇 가지 방법을 설명합니다.

obj.~ClassName()표기법을 사용하여 소멸자 함수를 명시 적으로 호출

소멸자는 개체가 자동으로 범위를 벗어나거나 사용자가 명시 적으로 호출하여 삭제 될 때 실행되는 특수 함수입니다. 이러한 기능은 일반적으로 주어진 객체에서 사용하는 리소스를 확보하는 데 사용됩니다. 소멸자를 멤버 함수로 명시 적으로 호출 할 수 있지만이를 수행 할 필요는 없습니다. 클래스 데이터 멤버가 동적으로 할당되는 대부분의 경우 리소스를 두 배로 늘릴 수 있습니다. 후자의 경우 일반적으로 프로그램이 비정상적으로 종료됩니다.

다음 예제에서는 두 개의 생성자와 유일한 데이터 멤버의 값을 검색하기위한 하나의 내장 메소드가있는MyClass라는 정의 된 클래스를 보여줍니다. 소멸자도 정의되고 생성자와 함께 해당 메시지를cout스트림에 인쇄하여 우리가 동작을 더 쉽게 조사 할 수 있도록합니다.

다음 예제 코드는 두 개의 소멸자 메시지를 인쇄하는데, 그중 하나는 명시적인 사용자 호출에 의해 트리거되고 다른 하나는 프로그램 종료시 자동으로 호출됩니다. 비록MyClass데이터 멤버가 생성자에서new연산자를 사용하여 할당 된 경우이 예제는 비정상적인 프로그램 종료로 이어 졌을 것입니다. 이중없는 오류 일 가능성이 있습니다.

#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

class MyClass {
 public:
  explicit MyClass(string s) : str(std::move(s)) {
    cout << "Constructor 1 executed\n";
  }

  MyClass(const MyClass& s) : str(string(s.str)) {
    cout << "Constructor 2 executed\n";
  }

  ~MyClass() { cout << "Destructor executed\n"; }

  string& getString() { return str; };

 private:
  string str;
};

int main() {
  MyClass str1("Hello There! ");

  cout << endl;
  cout << "str1: " << str1.getString() << endl;
  cout << endl;

  str1.~MyClass();

  return EXIT_SUCCESS;
}

출력:

Constructor 1 executed

str1: Hello There!

Destructor executed
Destructor executed

또는 다음 버전의 코드가 동일한 수의 생성자 / 소멸자 함수를 트리거하는 것을 볼 수 있습니다. 이는 본질적으로이 개념의 개념입니다. 따라서 마지막 예제가 오류없이 작동하더라도 명시 적으로 소멸자를 호출하는 것은 권장되지 않습니다.

#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

class MyClass {
 public:
  explicit MyClass(string s) : str(std::move(s)) {
    cout << "Constructor 1 executed\n";
  }

  MyClass(const MyClass& s) : str(string(s.str)) {
    cout << "Constructor 2 executed\n";
  }

  ~MyClass() { cout << "Destructor executed\n"; }

  string& getString() { return str; };

 private:
  string str;
};

int main() {
  MyClass str1("Hello There! ");
  MyClass str2(str1);

  cout << endl;
  cout << "str2: " << str2.getString() << endl;
  cout << endl;

  return EXIT_SUCCESS;
}

출력:

Constructor 1 executed
Constructor 2 executed

str2: Hello There!

Destructor executed
Destructor executed

고려해야 할 또 다른 경우는 클래스 객체가new연산자로 할당되고 프로그램이 종료되기 전에delete가 동일한 객체에서 호출되는 경우입니다. 마지막cout문은 설명자 함수가 실행 된 후 인쇄됩니다. 즉,delete연산자가 호출 될 때 설명자가 호출되었습니다.

#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

class MyClass {
 public:
  explicit MyClass(string s) : str(std::move(s)) {
    cout << "Constructor 1 executed\n";
  }

  MyClass(const MyClass& s) : str(string(s.str)) {
    cout << "Constructor 2 executed\n";
  }

  ~MyClass() { cout << "Destructor executed\n"; }

  string& getString() { return str; };
  string* getStringAddr() { return &str; };

 private:
  string str;
};

int main() {
  auto* str4 = new MyClass("Hello There! ");

  cout << endl;
  cout << "str4: " << str4->getString() << endl;
  cout << endl;

  delete str4;
  cout << "exiting" << endl;

  return EXIT_SUCCESS;
}

출력:

Constructor 1 executed

str4: Hello There!

Destructor executed
작가: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

관련 문장 - C++ Class