[완료] 클래스에서 어떤 메쏘드를 선언만 하고 구현하지 않는건 왜인가요 ?

parkon의 이미지

딱히 급한 문제는 아니지만 궁금해서 질문드리는 건데요,

제가 자주 쓰는 라이브러리 중에 root라는 라이브러리가 있는데
소스 파일을 들여다 보면 헤드 파일에 함수 원형을 선언을 하지만
실제로 구현하지 않는 경우가 종종 보이거던요.
예를 들면,

class TColloection : public TObject {
private:
   TCollection(const TCollection &);    //private and not-implemented, collections
   void operator=(const TCollection &); //are too complex to be automatically copied
   // ,,,
}

이런 식입니다.
이 클래스의 구현 파일인 TCollection.cxx에는 위의 두 메쏘드,
TCollection(const TCollection &);
void operator=(const TCollection &);
에 대한 구현이 없구요.

구현하지 않을꺼면 아예 처음부터 헤드 파일에 안쓰면 될 것 같은데
왜 헤드 파일에 저런 함수 원형을 선언했을까가 질문입니다.

참고로 저 TCollection 클래스는 추상 클래스로 자체로는 만들 수 없고
이로부터 다른 클래스들을 상속받아 쓰게 하는 용도입니다.

snowall의 이미지

상속받은 클래스에서 구현하겠죠

피할 수 있을때 즐겨라! http://melotopia.net/b

jick의 이미지

저 코드가 없다면 디폴트로 C++이 assignment constructor, assignment operator를 지원합니다. 하는 일은 단순히 class의 각 member를 복사하는 거죠. 즉 이 클래스를 이용하는 코드에서 다음과 같은 일을 할 수 있습니다.

TCollection A;
A.set_value(......);
// 어쩌구
TCollection B = A;  // calls TCollection::TCollection(const TCollection&) (compiler가 제공)
// 저쩌구
B = A;  // calls TCollection::operator=(const TCollection&) (compiler가 제공)

하지만 복사해서는 안되는 클래스의 경우 저런 식으로 private로 선언해 놓으면, 다른 코드에서 복사를 하려 할 때 에러가 나게 됩니다. (애당초 쓰지 못하게 만드는 게 목적이므로 구현은 없어도 됩니다.)

parkon의 이미지

jick님 설명듣고 보니 어느 정도 이해가 가는군요.
그렇다면, 어차피 private 영역 안에 있으니
이 함수들의 구현을 아무렇게나 해도,
예를 들어

class TColloection : public TObject {
private:
   TCollection(const TCollection &) {}    
   void operator=(const TCollection &) {} 
   // ,,,
}

이렇게 해 놓아도 저 위의 경우와 완전 똑 같은건가요 ?
klara의 이미지

어차피 불리지 않을 함수라면 결과적으론 같습니다만, 안쓸거라면 구현하지 않는게 좋습니다.
private영역이라고해도 같은 클래스내에서는 호출이 가능하기 때문에, 구현해두지 않으면 클래스내에서 실수로 호출했을 경우에 링크단계에서 에러를 뱉어줍니다.

oosap의 이미지

제가 알기로는 완전 다릅니다.

선언만 있는 경우에는 그 함수의 호출 자체가 불가능해지지만
구현이 되어있는 경우에는 그 함수의 호출이 가능해지니까요.
즉, 선언만 해두면 복사와 대입이 불가능한 클래스가 만들어지는데 반해
구현을 해두면 복사도 되고 대입도 되는 클래스가 만들어지죠.

C++ 기본서적들의 복사생성자와 대입연산자 그리고 디폴트 맴버 함수에 대해 알아보셔요...

Thanks for being one of those who care for people and mankind.
I'd like to be one of those as well.

oosap의 이미지

그리고 복사생성자와 대입연산자 오버로딩을 이런식으로 막아놓는 것은 흔한 기법입니다. 자주 볼 수 있다는 뜻이죠..

Thanks for being one of those who care for people and mankind.
I'd like to be one of those as well.

oosap의 이미지

제가 뭘 잘 모르고 답글을 쓴 것 같아요...
C++ 기본서적들의 복사생성자와 대입연산자 그리고 디폴트 맴버 함수에 대해 저도 좀 알아봐야겠어요 ^^;
제 글은 오류일 가능성이 큽니다. 아울러 이곳에 답글을 다는 걸 좀 해야 하지 않나 하는 의무감이 있었는데 오히려 잘못된 답글을 달게 된다면 안하느니만 못할 것 같다는 느낌이군요.. 저는 고수가 아니거든요... 흔히 하는 말 있죠. 제 글에 어떠한 보증이나 책임을 지지 않습니다 라는... 제 서명에 추가해야 할듯...

Thanks for being one of those who care for people and mankind.
I'd like to be one of those as well.

parkon의 이미지

아 그렇군요.
덕분에 이제 잘 이해한것 같습니다.
친절한 설명에 감사드립니다... ^^

parkon의 이미지

oosap님, 댓글 감사드립니다.
위의 내용은 private 영역 안에 있으니 (그래서 호출이 불가능하니) 서로 같지 않나 하는 내용이었구요,
말씀하신
> 복사생성자와 대입연산자 오버로딩을 이런식으로 막아놓는 것은 흔한 기법입니다.
역시 저만 몰랐단..., (농담입니다...^^)
덕분에 언제 저렇게 선언만 하는 건지 더 잘 이해하는데 도움이 되었습니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.