GUI에서 동적할당을 자주하는 이유?

noblepylon의 이미지

Sorry::Sorry(const wxString& title)
        : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(670, 615))
{
    Layout = new wxPanel(this, wxID_ANY, wxPoint(0, 0), wxSize(660, 575), wxBORDER_NONE); // 새 레이아웃 생성
 
    Buf = new wxString; // 문자열 생성
    for(int i = 0; i < 500; i++) {
        *Buf += wxT("I will not throw paper airplanes in class. ");
        #if defined __WXMSW__
            if(i % 2) *Buf += wxT("\r\n");
        #elif defined __WXMAC__
            if(i % 2) *Buf += wxT("\r");
        #elif defined __UNIX__
            if(i % 2) *Buf += wxT("\n");
        #endif
    }
    str = new wxTextCtrl(Layout, wxID_ANY, *Buf, wxPoint(0, 0), wxSize(660, 540), wxTE_MULTILINE); // 텍스트 박스 생성
    str->SetFont(wxFont(12, wxFONTFAMILY_DECORATIVE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false));
 
    import = new wxButton(Layout, wxID_EXIT, wxT("Import..."), wxPoint(460, 540), wxSize(100,35)); // "Import..." 버튼 생성
    Connect(wxID_EXIT, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Sorry::OnImport));
    import->SetFocus();
    quit = new wxButton(Layout, ID_IMPORT, wxT("Quit"), wxPoint(560, 540), wxSize(100,35)); // "Quit"버튼 생성
    Connect(ID_IMPORT, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Sorry::OnQuit));
 
    SetIcon(wxIcon(wxT("std")));
    this->Center();
}

위의 코드는 버튼 2개와 텍스트 박스 하나로 구성된 아주 단순한 프로그램입니다.
그런데 버튼 하나를 만들려고 해도 일일이 new구문으로 동적할당을 한 뒤에 포인터에 대입을 해 주어야 하는군요.

GUI에서 동적할당을 주로 하는 이유가 있나요?

klyx의 이미지

이 이유가 맞는진 모르겠지만, 저같은 경우는 컴파일 의존성을 줄이기 위해서 동적할당을 이용합니다.
이건 딱히 GUI라서 그런건 아니구요, 똑같은 인스턴스라도 멤버로 포인터를 가지고 있는 경우는 전방선언만으로 컴파일이 가능하기 때문이죠.
wxWidgets은 어떤지 모르겠지만, Qt의 경우는 동적할당해도 대부분 알아서 삭제되기 때문에, 메모리 누수 걱정도 없구요.

그리고 만약에 적으신 예제에서 버튼이 멤버로 들어가있는게 아니라면, 동적할당하지 않고 그냥 stack에 넣으면 생성자 종료될때 없어져버릴테니, 당연히 동적할당을 해야겠네요.

ironiris의 이미지

디자인 편집기가 없거나 시원치 않아서?

klyx의 이미지

어떤 디자인 편집기를 말씀하시는건지 모르겠네요.
Qt에는 예를 들어 MFC의 그것보다 훨씬 낫다고 생각하는 designer가 있거든요.
wxWidgets은 모르지만, 그쪽에도 GUI용 디자이너가 있는걸로 알고 있고요.
그리고 코드는 디자이너가 있고 없고와는 전혀 관계없습니다.

ironiris의 이미지

제목만 보고 코드는 안본 상태에서 쓴 글입니다.
특정언어나 편집기를 비하하는 의도가 아닙니다.

noblepylon의 이미지

위의 예제에서 import와 quit버튼은 엄연히 Sorry객체의 멤버입니다.
그래서 마음만 먹는다면 포인터를 쓰지 않을 수 있지요.

그런데도 불구하고 wxWidgets예제를 보면 한결같이 포인터를 쓰더군요.
GUI요소를 그냥 멤버변수로 잡았을때와 멤버포인터로 잡았을 때 어떤 차이점이 존재하나요?


wxButton* quit = new wxButton(Layout, ID_IMPORT, wxT("Quit"), wxPoint(560, 540), wxSize(100,35)); // "Quit"버튼 생성


wxButton quit = wxButton(Layout, ID_IMPORT, wxT("Quit"), wxPoint(560, 540), wxSize(100,35)); // "Quit"버튼 생성

사이의 차이점이 알고 싶은겁니다.
---
"The truth will make you free."(John 8:32)
"I am the way, and the truth, and the life: no one comes to the Father but through Me."(John 14:6)

---
“내게 능력주시는 자 안에서 내가 모든 것을 할 수 있느니라.”(빌립보서 4:13)

doldori의 이미지

저도 qt를 배울 때 이 점이 궁금했었습니다.
책을 보면 widget의 포인터를 멤버로 가지면서 동적 할당을 하더군요.
저는 두 가지 정도의 이유가 생각납니다.

1. 생성/소멸 시점의 제어
동적 할당의 특징은 개체의 생성과 소멸 시점을 제어할 수 있다는 점이지요.
항상 생성할 필요가 없는 widget이 있을 수 있습니다.
이런 것들은 필요한 시점이 되었을 때만 동적으로 생성하는 것이 성능상으로 유리합니다.
마치 lazy evaluation과 같은 것이지요.

2. 다형성
예를 들어 Button 클래스를 상속받은 TextButton과 ImageButton 클래스가 있다고 합시다.
그리고 사용자의 설정에 따라 버튼이 다르게 나타나게 하고 싶다면
Button의 포인터를 갖고 있다가 동적으로 생성하면 되겠지요.

이런 이유에 해당되지 않는 widget은 동적 할당을 쓰지 않아도
동작에는 아무 차이가 없을 것 같습니다.

brucewang의 이미지

widget에 대해 전혀 아는게 없지만, doldori 님께서 설명해주신 것을 보니
마치 decorator pattern을 위젯에서 구현하기 위해 그런것 같은 느낌이네요.
qt꾀 오래된 걸로 알고 있는데 그때부터 그런 개념이 있었다니..
대단합니다.

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

semmal의 이미지

doldori님이 잘 설명해주셨네요.

더하고 뺄 내용이 없을듯...
------------------------------
How many legs does a dog have?

------------------------------
How many legs does a dog have?

wish의 이미지

음 제가 무엇인가 왕창 잘못 생각하는 것 같기도 하지만 ;;;

wxButton* quit = new wxButton(Layout, ID_IMPORT, wxT("Quit"), wxPoint(560, 540), wxSize(100,35)); // "Quit"버튼 생성
 
wxButton quit = wxButton(Layout, ID_IMPORT, wxT("Quit"), wxPoint(560, 540), wxSize(100,35)); // "Quit"버튼 생성

후자처럼 하면 일단 스택에다 wxButton 인스턴스를 생성한다음에 quit에다 메모리 복사를 하게 되고,
전자처럼 하면 인스턴스는 힙에다 생성하고, 그것을 가르키는 포인터만 스택에 들어갔나 나왔다 하지 않나요?
너무 씨적인 생각인가 ;;

gamdora의 이미지

그럼 이렇게 하면 되지요. :)

wxButton quit(Layout, ID_IMPORT, wxT("Quit"), wxPoint(560, 540), wxSize(100,35)); // "Quit"버튼 생성
wish의 이미지

Quote:

wxButton quit = wxButton(Layout, ID_IMPORT, wxT("Quit"), wxPoint(560, 540), wxSize(100,35)); // "Quit"버튼 생성
wxButton quit(Layout, ID_IMPORT, wxT("Quit"), wxPoint(560, 540), wxSize(100,35)); // "Quit"버튼 생성

전자와 후자 간에 차이가 있나요?

제가 아는 한에서는 동일한 코드인걸로 알고 있습니다만... 혹시나 해서 테스트 해봤는데, 똑같은 어셈코드를 생성합니다~

kaeri17의 이미지

소스 자체만 보면 위에것은 임시객체를 생성하고 그것을 통해 복사생성자로 quit을 생성하는 것이고 두번째 것은 바로 생성자를 통해 생성하는 것이죠.

quit의 생성자와 복사생성자가 다르다면 다른 결과를 낼 것으로 예상됩니다.

-------------

라고 생각 했는데;;

복사생성자가 아니라 그냥 생성자가 호출되는군요. g++이나 VC++이나 마찬가지로군요. 표준을 한번 찾아봐야겠습니다.

ikpil의 이미지

GUI이기 때문은 아니라고 생각 합니다. 그리고...
굳이 동적할당을 하지 않아도 되는 구조라면 하지 않습니다.

함수 내부에 버튼을 생성하게 되면, 편하겠죠^^

이럴 때 버튼을 계속 가지고 있는게 편한가? 쓰고 지우는게 편한가? 일텐데..
저 같은 경우 계속 사지고 있겠다 라고 결정내린다면

이것을

    str = new wxTextCtrl(Layout, wxID_ANY, *Buf, wxPoint(0, 0), wxSize(660, 540), wxTE_MULTILINE); // 텍스트 박스 생성
    str->SetFont(wxFont(12, wxFONTFAMILY_DECORATIVE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false));

이렇게

    static wxTextCtrl wsTC(Layout, wxID_ANY, *Buf, wxPoint(0, 0), wxSize(660, 540), wxTE_MULTILINE); // 텍스트 박스 생성
    str = &wsTC;
    str->SetFont(wxFont(12, wxFONTFAMILY_DECORATIVE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false));

이렇게 바꾸면, 근심 걱정이 사라집니다.

댓글 달기

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