c++ 클래스 초기화 시에...

mg2000의 이미지

제가 아래와 같은 클래스를 만들었는데요.

class A
{
private:
    unsigned char *p;
    int size;
public:
    A() : p(NULL), size(0) {}
    A(int size)
    {
        A();
        Alloc(int size);
    }
    void Alloc(int size)
    {
        if (p != NULL)
            free(p);
        p = (unsigned char *)malloc(size);
        this->size = size;
    }
};

이런 클래스를 정의하고, 아래와 같이 사용하려고 했더니...

A a(100);

A(int size)의 생성자에서 기본 생성자를 호출해서, 멤버 변수를 초기화 하고, 메모리

할당을 시킬 줄 알았더니, 기본생성자에 있는 초기화 부분이 호출이 안되는 것 같더라고요.

그래서 할당시에 p가 NULL이 아니어서 엉뚱한 곳을 free를 호출해 죽어버리는데,

초기화를 이렇게는 할 수 없는 것인가요?

navidad의 이미지

생성자 내에서 overloading된 다른 생성자를 호출하는 것은 불가능한 것으로 알고 있습니다.

EC++ 어딘가에서도 언급하고 있는 내용인 것으로 어렴풋 기억하는데..

원하는 작업을 하려면 init과 같은 초기화를 담당하는 일반 메소드를 만들고,

각 생성자에서 초기화 메소드를 호출하는 방법으로 처리하는 것으로 알고 있습니다.

=================================
나비아빠

=================================
나비아빠

brucewang의 이미지

생성자 내부에서 명시적으로 다른signature의 생성자를 호출할수는 없는것으로 알고 있습니다. 생성자가 사실 이름이 없는 함수인데다, 객체생성을 위의 코드처럼 다른 것에 양도할수 있도록 설계 되어 있지 않죠.

A(); 가 호출이 안된다는것이 아니라, 그 문장에서 별도의 임의의 A객체가 생성되고 결국 소멸되어 버리게 됩니다.

그래서 원하시는 의도대로 하시려면, 별도의 공통 초기화 함수 (예를들어 init() 같은 함수)를 만드셔서 각각의 생성자가 그 초기화 함수를 불러주도록 하시는게 가장 편한 방법이 아닐까 싶네요...

그리고, 이런 trick이 제대로 먹힐런지 모르겠네요... 한번 사용중인 컴파일러에서 시도해 보시죠.. 예를 들어...

A::A(){
new (this) A(0,0,0,0,0,0);
}

-------------------------------------------------
$yes 4 8 15 16 23 42

-------------------------------------------------
$yes 4 8 15 16 23 42

chadr의 이미지

A(int size) : A()
{
Alloc(int size);
}

와 같이 생성자 위임이 가능하긴 합니다.

비교적 최근 표준이므로 너무 오래된 컴파일러에서는 지원하지 않습니다.
테스트 해보니 최근 gcc와 vs2005이상에서 제대로 지원 했던것 같습니다.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

M.W.Park의 이미지

위에 분 말씀대로 되구요.
제가알기론 아주 오래전에도 되었던 거같네요. C++을 처음 썼던게 90년대 중반쯤이니....

A() : A(100) --> 요런 형태도 되었던듯... 한번 실험해보세요. ^^;

-----
오늘 의 취미는 끝없는, 끝없는 인내다. 1973 法頂

-----
오늘 의 취미는 끝없는, 끝없는 인내다. 1973 法頂

Fe.head의 이미지

class CA
{
private:
    int     m_a;
    int     m_b;
 
public:
    CA()    :   CA( 10, 10 )
    {
        cout << "CA()\n";
    }
 
    CA( int a, int b )  :   m_a( a ), m_b( b )
    {
        cout << "CA( int a, int b )\n";
    }
 
    ~CA()
    {
        cout << "~CA()\n";
    }
};
 
A.C: In constructor ‘CA::CA()’:
A.C:12: error: type ‘CA’ is not a direct base of ‘CA’

위코드에서 에러가 나는데.. 뭐가 잘못 된걸까요?
-----------------------
과거를 알고 싶거든 오늘의 네 모습을 보아라. 그것이 과거의 너니라.
그리고 내일을 알고 싶으냐?
그러면 오늘의 너를 보아라. 그것이 바로 미래의 너니라.

고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"

brucewang의 이미지

윗 분들께서 설명해 주신 부분은 parent class의 생성자에 초기화 과정을 일부 위임하는것을 의미하셨던 것 같네요.
최초의 parent를 잘 디자인해서 자식들을 파생하시면, 윗분들의 말씀하신 스타일의 코딩도 깔끔해 집니다.

-------------------------------------------------
$yes 4 8 15 16 23 42

-------------------------------------------------
$yes 4 8 15 16 23 42

댓글 달기

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