[문제해결] C++ 에서 객체에 대한 Initialize 나 Finalize 메소드를 별도로 구현하는 이유는 뭘까요?

litmus80의 이미지

안녕하세요.

문득 궁금한 점이 생겼습니다.

C++에서 객체에대한 초기화(Initialize) 나 해제(Finalize) 메소드를 구현하는 이유는 뭘까요?

얼핏 생각해보면 그냥 생성자나 소멸자를 이용해도 좋을 것 같은데...

물론 정의하고 구현하기 나름이겠지만..

혹시 반드시 이렇게 클래스를 정의할 필요가 있거나,
이런 방식으로 객체를 보다 효율적으로 관리할 수 있는 특수한 경우가 있나요?

궁금합니다.

xylosper의 이미지

그저 단순한 변수의 묶음이 아닌이상, 일반적으로는 구현하지 않는 경우가 드뭅니다.
여러가지 이유가 있겠지만, 예를 들자면, 클래스 내부에서 할당하는 자원들은, 클래스외부에서 해제해주길 바라기보다는, 내부에서 알아서 처리해주는게 좋을뿐만아니라, 일반적으로 내부자원은 private영역에 들어가므로 외부에서는 해제해줄수도 없습니다.
이런 경우 소멸자에서 자원해제를 해주도록 한다면 알아서 자동으로 해제가 되겠지요.
생성자의 경우는 변수나 자원의 초기화에 유용합니다.
그리고 이것은 결코 특수한 경우가 아니라 일반적인 경우입니다.

winner의 이미지

제가 보기에는 예를 들어 fstream에 왜 open과 close가 있나고 묻는 것 같습니다. 정확히 같은 질문은 아니겠습니다만.... 제 생각에는 객체의 모든 자원을 초기화하고 정리하는 member 함수는 제작할 이유가 거의 없지만 만일 그 객체를 자유공간에 만들어야 한다면 빈번하게 새로 생성하고 소멸시키기에는 부담이 될 수도 있을 것 같네요. 그것이 아니면 객체의 모든 자원을 자주 한꺼번에 변경할 필요가 있으면 setAll(...) 이라는 member 함수를 만들면 이것이 초기화 함수라고 생각할 수도 있을 것 같군요. 하지만 일반적으로는 잘 사용되지 않을 것 같은데요. C++ 세계에서는 RAII라고 해서 생성자와 소멸자를 쓰는 것이 일반적이니까요.

xylosper의 이미지

그렇네요. 생성자와 소멸자는 또 따로 언급되있었네요. 이미알고 계신 얘기를 떠들어대서 죄송합니다.
winner님말씀대로 생성자나 소멸자외에 초기화를 위한 함수를 따로 만드는 경우(그것도 public으로)라면, 그 초기화라는 동작을 여러번 수행하는것이 예상되고, 새로운 객체를 만들기엔 부담되는 경우겠네요.

litmus80의 이미지


아직 궁금증이 풀리지는 않았지만... 갑자기 그럴듯한 근거가 생각났어요.

Initialize의 경우엔 말이죠. 생성자는 리턴형이 없기 때문에 클래스 내부에서 여러가지 리소스에 대한 할당이 제대로 이뤄졌는지 확인하기 힘들어서 Initialize 메소드를 별도로 사용할 만하다는 생각이 드네요..

혹시 제 말도 일리가 있나요? ㅎㅎ

그렇다면 Finalize는?... :( 그냥 소멸자로 대체할 수 있는거 같기도 하고... 끄응...

winner의 이미지

Memory 할당을 맏는 new 연산자도 bad_alloc 예외를 던지는 것이 기본이니까요.
하지만 예외가 부담이 된다면 의미있는 이야기입니다.

litmus80의 이미지

실수로 댓글을 중복해서 작성했네요;; 댓글은 삭제 기능이 없는 건가요? ;(

bearchit의 이미지

코드의 중복을 줄이고 혹시 일어날 수 있는 리소스 누수를 미연에 막기 위함이 아닐까요?
꼭 객체가 파괴되는 시점이 아니라도 리소스를 해제해야 하는 경우가 있으니
리소스를 해제하는 코드를 Finalize()에 넣어서 객체 내부에서 리소스 해제시 이 메소드를 호출하게끔 하는거죠.
근데.. 제가 질문을 제대로 이해했는지 모르겠네요.. ㅡㅡa

winner의 이미지

우선 class c {int a, b;} 같은 단순 변수의 묶음 형태에서 소멸자가 아닌 공개정리함수는 필요가 없을 겁니다. 하지만 setAll 같은 공개초기화함수는 작성할 수 있겠지요. 그리고 내부에 system 자원을 동적으로 받는 member 변수가 있다면 공개초기화 함수와 공개정리함수를 작성하는 것이 기본입니다. 기존 자원을 반환하고 새로운 자원을 받아온다면 member 변수를 조정하기 위해서 전체 객체를 새로 생성하고 기존 객체를 소멸시키는 것은 무리가 많으니까요. 그리고 이런 공개초기화 함수와 공개정리함수는 각각 생성자와 소멸자에서 사용함으로써 중복을 줄이고, programmer가 명시적으로 자원을 반환하는 함수를 호출하지 않아도 자동으로 반환하도록 해야겠죠. 이것이 정석일테고, 표준 library를 봐도 그런 형태로 되어 있습니다.
마지막으로 이런 형태는 흔히 3-rule이라고 하는 것과 연관이 있습니다. 필요하다면 복사생성자와 대입연산자에 대해서도 세심하게 고민을 하셔야 한다는 뜻이죠.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.