C++에서 extern을 쓰는것이 객체지향적으로 맞는지요?

gugudan의 이미지

스레드가 있는데 이 스레드를 공유할 list가 있는데
스레드를 파일로 분리를 했는데 분리 하다 보니..
각 클래스의 객체를 서로 참조를 할 수 없게 되었네요..
그래서
extern을 이용해서 공유를 했는데
이 구조가 괜찮은지요?

좀 추상적인가요?

blitzerg의 이미지

객체지향은 그저 객체지향일뿐 extern/static 개념과는 괘를 달리하는 기능입니다.

마치 볼펜이 좋아? 종이가 좋아? 라고 하는 것과 같습니다. 글을 쓰려면 볼펜도 있고 종이도 있어야 하죠. 종이가 없어도 볼펜은 다른 곳에 쓸수 있고, 볼펜이 없어도 종이에 다른 필기구로 쓸 수 있는 것과 같은 것입니다.

정확히 extern/static(class의 static이 아님;c++에서는 static 키워드는 생략 권고) 개념은 C에서 외부 모듈에 선언된 루틴을 부르기 위한 규칙에 불과합니다.

서로의 기능은 서로 기능상의 연관이 없으며 어떻게 써도 문제가 있다고 하긴 힘듭니다.

문제는 OO설계가 제대로 되었고 제대로 구현되었느냐하고 파일간의 인터페이스가 얼마나 제대로 정의되었느냐의 문제겠지요.

버려진의 이미지

좀 다른 이야기지만 thinking in c++에서는 extern의 사용도가
c보다 c++에서는 줄어들었다 라고 이야기 하더군요.

doldori의 이미지

촙5 wrote:
좀 다른 이야기지만 thinking in c++에서는 extern의 사용도가
c보다 c++에서는 줄어들었다 라고 이야기 하더군요.

그 이유가 궁금하네요. 전역 개체는 되도록이면 피하는 것이 바람직한 스타일이지만
그 부분은 C에 비해서 별다른 특징은 없는 것 같습니다.
내부 연결을 갖도록 하기 위한 static 대신 unnamed namespace를 쓰라는 말은
하더군요. static이 워낙 다양한 의미로 사용되기 때문에 혼란을 주기 쉬워서요.
zelon의 이미지

으음... 맞을지는 모르겠지만,

extern 보다는 디자인 패턴 중 singleton 을 이용한 방법은 어떨까요? 정말 초간단한 리스트만 있는 경우라면 상관없겠지만 그와 연동되는 함수가 하나 이상이라면 singleton 으로 만들면 좋을 듯 합니다. ^^

-----------------------------------------------------------------------
GPL 오픈소스 윈도우용 이미지 뷰어 ZViewer - http://zviewer.wimy.com
블로그 : http://blog.wimy.com

blitzerg의 이미지

Quote:

그 이유가 궁금하네요.

c++에서 extern의 사용도가 줄어든 이유를 생각외로 간단할 것 같습니다.

c에서는 모듈을 만드려면 파일단위로 해야했지만

c++에서는 클래스가 모듈이니까 파일간 인터페이스가 아니라 클래스간 인터페이스로 변화한 것 뿐 아닐까요?

doldori의 이미지

blitzerg wrote:
Quote:

그 이유가 궁금하네요.

c++에서 extern의 사용도가 줄어든 이유를 생각외로 간단할 것 같습니다.

c에서는 모듈을 만드려면 파일단위로 해야했지만

c++에서는 클래스가 모듈이니까 파일간 인터페이스가 아니라 클래스간 인터페이스로 변화한 것 뿐 아닐까요?


그것은 이유가 되지 못합니다. 클래스는 새로운 형을 정의하겠다는 것이지
클래스 개체가 전역이냐 지역이냐와는 별로 관계가 없지요.
blitzerg의 이미지

제 말은 결국 원래 C에서 extern과 static이라는 형태가 모듈간 인터페이스에 불과했다는 말입니다.

C++ 프로그램을 작성할 때 만약 하나의 클래스(또는 namespace)당 하나의 파일로 만든다면 extern 선언은 당연히 필요하게 됩니다.

그러나 만약 하나의 파일에 모든 클래스(또는 namespace)가 들어가 있다고 하면 그러한 extern 선언은 필요없게 된다는 뜻이지요.

클래스나 namespace는 반쯤은 모듈 기능을 제공하는 역할이지 않습니까?

예를들어

a.c

int v;
void f() {}

b.c

extern int v;
extern void f();
void g() { v=0; f(); }

이렇게 하던 것을

c.cpp

namespace A
{
  int v;
  void f() {}
}

namespace B
{
  void g() {A::v=0; A::f(); }
}

또는

d.cpp

class A
{
public:
  static int v;
  static void f() {}
};

class B
{
public:
  static void g() {A::v=0; A::f(); }
}

이렇게 할 수 있게 된거죠.[/code]

doldori의 이미지

c.cpp에 정의된 개체나 함수를 다른 소스에서 참조하려면 다음과 같은 선언은
어차피 들어가야 됩니다. 물론 이런 내용은 헤더에 넣겠지만요.

namespace A 
{ 
  extern int v; 
  extern void f(); // 함수에서 extern은 생략 가능하나 그것은 편의성을 위한 것일 뿐입니다.
} 

namespace B 
{ 
  extern void g(); 
} 

C에서 인터페이스 제공을 위한 extern 함수들이 클래스의 인터페이스로 들어가면서
extern이 줄었다는 뜻이라면 그건 이해가 가는군요. 그런데 클래스 개체(인스턴스)
자체를 전역으로 하느냐 지역으로 하느냐와는 여전히 무관합니다. 보통 전역으로
만들어서 문제가 되는 것은 함수보다는 변수 쪽 아닌가요?
blitzerg의 이미지

클래스 개체가 전역이냐 지역이냐도 분명히 관계가 있다고 볼 수 있지 않나요?

클래스 인스턴스는 개념상 다이나믹 모듈로 볼 수 있습니다.

그 인스턴스가 전역이든 지역이든 같은 파일에서 생성된다면 링커에게 이름을 가르쳐주지 않고도 얼마든지 사용할 수 있는거 아닌가요?

제 생각일 뿐일 수도;;

댓글 달기

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