[질문] 이런 코드를 좀 간단히 해결 할 수 있는 방법이 없을까요?

ljh6341의 이미지

간단한 script를 만들어서 원하는 자료형으로 얻어오고 싶은데요.

아래와 같은 함스들을 간단하게 할수 있는 방법이 있을까요.

short GetData_BYSHORT(int _idx);
WORD GetData_BYUSHORT(int _idx);
int GetData_BYINT(int _idx);
DWORD GetData_BYUINT(int _idx);
char* GetData_BYSTRING(int _idx);
BYTE* GetData_BYPTRBYTE(int _idx);

템플릿 같은 걸로 간단하게 만들어 버리는 방법을 알고 싶습니다.

불쌍한 중생 구제 좀 .. ^^;;

모두 즐거운 하루 되세요.

ssehoony의 이미지

함수명이 기능을 정확히 대변하고 있지 않고해서,
선언만 갖고 가능하다 불가능하다를 알 수 없을 듯 하군요.

함수 정의도 2~3개 정도 예시로 해주시면 도움을 드릴 수 있을지도...

pok의 이미지

맵과 함수포인터를 이용하는것은 어떨까요? 리턴형이 되는것들을 하나의 클래스나 구조체로 만들어서 파라미터로 넘겨버리고(예를들면 ReturnData)

class ReadScript {
    ...
    GetData_BYINT(ReturnData* _pReturnData);
    map<string, void* (ReadScript::*)(ReturnData*)> getData;
    getDate["int"] = GetData_BYINT;
    ...
}
...
ReturnData aReturnData;
ReadScript aReadScript;
...
if(int형을 읽어들이고 싶어요){
    aReadScript.getDate["int"](&aReturnData);
}
...

이런식으로 사용해도 괜찮을것 같군요
ljh6341의 이미지

간단한 스크립트 클래스를 만들고 있습니다. 윈도우, 리눅스 공용으로요.
쓰고 읽고, 수정도 가능하게 만드는 중이구요.

답글 달아주신 분들께 감사드립니다. 덕분에 여러가지로 고민을 해봤습니다.

일단 유니온으로 해결을 보았습니다.

최대한 독립적인 코드를 만들기 위해 STL을 피했으며, 자주 사용할 수 있는 부분이므로 함수포인터 사용도 피하는게 좋을 것 같았습니다.
(요즘은 STL을 사용하지 않는 부분을 찾기가 더 힘들 정도긴 하지만.. 개인적으로 좋아하지는 않습니다. 그래서, 만약 효율적인 부분에서 손해를 안보고 피할 수 있다면 최대한 피하는 편이라서요. ^^;; )

( 음.. 이건 잘 모르는 부분이라 질문입니다. 함수 포인터를 사용하려면 각각의 기능을 하는 함수를 만들어서 연결해줘야 하는데요. 만약 지정한 함수들이 골고루 사용된다는 조건이 된다면 캐쉬 적중률은 역시 손해를 보는 거겠죠? 하나의 함수로 만드는 것보다는요. 예전에 배운 내용인데, 지금도 이렇게 통용되나요?)

아래와 같은 형태로 처리했습니다만.. 하나의 함수로 해결해서 좋긴한데, 사용자들이 불편을 느낄것 같습니다. ^^; 좀 더 사용하기 편하도록 계속 수정을 할 예정입니다.

보시고 더 좋은 방법이 있으신 분들은 조언 부탁드립니다.

enum
{
    eDT_CHAR,
    eDT_SHORT,
    eDT_INT,
    .
    .
    eDT_STRING,
}eDT_TYPE;

typedef union
{
    unsigned char CHAR,
    short               SHORT,
    int                   INT,
    .
    .
    char *              STRING,
}unVARIANT;

bool GetData(eDT_TYPE _eType, unVARIANT * _unRet, char * _strName)
{
    // _strName으로 원하는 데이터를 찾고..
    switch(_eType)
    {
    case eDT_SHORT:
         _unRet->SHORT = // 데이터 처리;
         break;
       .
       .

    }
}

모두 모두 행복한 하루 되세요. ^^

jyoung의 이미지

Quote:
( 음.. 이건 잘 모르는 부분이라 질문입니다. 함수 포인터를 사용하려면 각각의 기능을 하는 함수를 만들어서 연결해줘야 하는데요. 만약 지정한 함수들이 골고루 사용된다는 조건이 된다면 캐쉬 적중률은 역시 손해를 보는 거겠죠? 하나의 함수로 만드는 것보다는요. 예전에 배운 내용인데, 지금도 이렇게 통용되나요?)

흐음. 이건 경우에 따라 다를거 같네요. 여러개의 함수를 사용하는 거에 비해서 하나의 함수로 만드는게 크기가 작아지는 경우라면 하나의 함수로 만드는게 캐쉬 적중을 높일 수 있다고 생각합니다. 하지만, 여기서 사용하신 것 같은 2~3줄 정도의 길이의 함수라면, 각각의 함수로 나누어서 inline을 하게 하면, 아예 함수 호출 자체를 없앨 수 있기 때문에 캐쉬를 사용하는데 있어 효율적일 거 같네요.

될대로 되라지..

only2sea의 이미지

ljh6341 wrote:
간단한 스크립트 클래스를 만들고 있습니다. 윈도우, 리눅스 공용으로요.
쓰고 읽고, 수정도 가능하게 만드는 중이구요.

스크립트 클래스가 무엇인지 잘 모르겠는데 인터프리터 같은 것을 만드신다는 뜻인가요?

ljh6341 wrote:
최대한 독립적인 코드를 만들기 위해 STL을 피했으며, 자주 사용할 수 있는 부분이므로 함수포인터 사용도 피하는게 좋을 것 같았습니다.
(요즘은 STL을 사용하지 않는 부분을 찾기가 더 힘들 정도긴 하지만.. 개인적으로 좋아하지는 않습니다. 그래서, 만약 효율적인 부분에서 손해를 안보고 피할 수 있다면 최대한 피하는 편이라서요. ^^;; )

코드를 보고 꼭 C를 써야 하는 상황인 것처럼 생각했는데 STL 말씀을 하시니 C++로 하시는가 봅니다. STL은 효율적으로 구현되어 있어서 실행시간의 오버헤드는 매우 적다고 생각합니다만...

ljh6341 wrote:
( 음.. 이건 잘 모르는 부분이라 질문입니다. 함수 포인터를 사용하려면 각각의 기능을 하는 함수를 만들어서 연결해줘야 하는데요. 만약 지정한 함수들이 골고루 사용된다는 조건이 된다면 캐쉬 적중률은 역시 손해를 보는 거겠죠? 하나의 함수로 만드는 것보다는요. 예전에 배운 내용인데, 지금도 이렇게 통용되나요?)

아마 어떤 데이터를 얻을지를 결정하는 GetData()를 하나의 함수로 만들어서 switch 문을 활용하여 리턴을 할지, 아니면 함수 포인터로 분기할지를 생각하시는 것이라고 한다면 아마도 위와 같은 경우에서는 하나의 함수로 하는 것이 나을 가능성이 있을 것 같습니다. 스위치로 분기할 위치가 매우 가깝기 때문이죠. 함수 포인터로 해서 인라인을 한다고 해도 인라인의 효과는 얻을 수 없습니다. 직접적으로 static한 호출이 이루어진다면 인라인 확장이 일어나겠지만 함수 포인터로 호출을 하는 것은 런타임에 결정되므로 인라인 확장이 일어나지 않겠지요.

ljh6341 wrote:
아래와 같은 형태로 처리했습니다만.. 하나의 함수로 해결해서 좋긴한데, 사용자들이 불편을 느낄것 같습니다. ^^; 좀 더 사용하기 편하도록 계속 수정을 할 예정입니다.

보시고 더 좋은 방법이 있으신 분들은 조언 부탁드립니다.


variant 형을 이와같이 유니온으로 처리하는 구현을 어디선가 본적은 있습니다. 조언을 드리려면 구체적으로 어떻게 이것이 필요한 것이며 어떻게 사용될 것인지를 알아야 할 것 같습니다.
pok의 이미지

Quote:

// _strName으로 원하는 데이터를 찾고..

이부분은 어떻게 구현하셨나요?
저도 비슷한것을 구현했었는데 당시에 문제 역시 문자로 생성을 결정한다는 것이었습니다.

2가지 방법을 생각했었는데, 첫째는 Factory Method를 이용하는 방법과 다른 하하는 제가 처음에 제시했던 map과 simple factory를 사용하는 방법이었습니다.

근데, 문자로 생성될 객체를 결정하는 문제는 최악의 경우 O(n)시간이 걸릴뿐만 아니라 찾을때마다 strcmp계열의 함수를 호출해야하기 때문에 내부적으로 트리를 사용하는 map형태로 가는것으로 결론을 지었었습니다.

비슷하게 문자로 생성을 결정할것을 찾고 strcmp계열로 문자를 찾는다면 그냥 map으로 하는게 더 나을것같은데, 음.. 어떨까요?

익명 사용자의 이미지

함수템플릿을 사용하여 간단하게 구현해 보았습니다. 사용방범은 아주간단합니다. 스트링이나 바이너리의 경우는 읽어오는 방법이 조금다른데 두단계로 나우어 볼때 읽어올 길이와 실데이터를 읽어와야 합니다. 이 다른 작업을 하기 위해서 클래스 특화를 사용하면 됩니다. 아래 예제를 참고 하세요^^

#include "string.h"
#include <string>

char g_data[1024]={0};

template<class T> void SetData(int index, const T & data)
{
memcpy(&g_data

    , &data, sizeof(T));
    }
    template<class T> T & GetData(int index)
    {
    return (T&)g_data
      ;
      }

      template<> std::string & GetData<std::string>(int index)
      {
      char len;
      static std::string str;
      len=(char)g_data

        ;
        str.insert(0, g_data+sizeof(char), len);
        return (std::string &)str;
        }

        int main(int argc, char* argv[])
        {
        char ch='a';
        int num=10;
        SetData<char>(0, ch);
        SetData<int>(1,num);

        printf("%c\n", GetData<char>(0));
        printf("%d\n", GetData<int>(1));

        char * str="test string!";
        SetData<char>(0, strlen(str));
        strcpy(g_data+1, str);

        printf("%s\n", GetData<std::string>(0).c_str());
        return 0;
        }

        doldori의 이미지

        Boost.Any를 써도 좋겠군요.

        ljh6341의 이미지

        Quote:
        스크립트 클래스가 무엇인지 잘 모르겠는데 인터프리터 같은 것을 만드신다는 뜻인가요?

        예. 윈도우의 registry처럼 만들었다가 좀 더 확장중입니다. 현재 1차 완료된 상태입니다. 2차 설계 중인데 하다보니 마치 게임 스크립트 같아 지는거 같은 기분입니다. :wink:

        Quote:
        코드를 보고 꼭 C를 써야 하는 상황인 것처럼 생각했는데 STL 말씀을 하시니 C++로 하시는가 봅니다. STL은 효율적으로 구현되어 있어서 실행시간의 오버헤드는 매우 적다고 생각합니다만...

        저도 동감합니다. 단, 의존성을 낮추기 위해 꼭 필요한 경우 아니면 사용을 안하고 있습니다. 제 코드를 2차적으로 사용하는 사람이 원한다면 수정하겠죠.

        Quote:
        variant 형을 이와같이 유니온으로 처리하는 구현을 어디선가 본적은 있습니다. 조언을 드리려면 구체적으로 어떻게 이것이 필요한 것이며 어떻게 사용될 것인지를 알아야 할 것 같습니다.

        ado에서 이와같이 처리하는걸 참고해서 만들었습니다. ^^

        몇번이나 답변에 답을 하면서 제 질문에 대한 내용을 자세히 적으려고 했는데, 쉽지가 않습니다만 계속 노력해 보겠습니다.

        Quote:
        비슷하게 문자로 생성을 결정할것을 찾고 strcmp계열로 문자를 찾는다면 그냥 map으로 하는게 더 나을것같은데, 음.. 어떨까요?

        string을 받아서 hash로 처리합니다. strcmp가 아닌 unsigned long형의 비교라서 방대할 정도의 양이 아니라면 속도에서는 문제가 안될 것 같습니다.

        Quote:

        함수템플릿을 사용하여 간단하게 구현해 보았습니다. 사용방범은 아주간단합니다. 스트링이나 바이너리의 경우는 읽어오는 방법이 조금다른데 두단계로 나우어 볼때 읽어올 길이와 실데이터를 읽어와야 합니다. 이 다른 작업을 하기 위해서 클래스 특화를 사용하면 됩니다. 아래 예제를 참고 하세요^^

        #include "string.h" 
        #include <string> 
        
        
        char g_data[1024]={0}; 
        
        template<class T> void SetData(int index, const T & data) 
        { 
        memcpy(&g_data[index], &data, sizeof(T)); 
        } 
        template<class T> T & GetData(int index) 
        { 
        return (T&)g_data[index]; 
        } 
        
        template<> std::string & GetData<std::string>(int index) 
        { 
        char len; 
        static std::string str; 
        len=(char)g_data[index]; 
        str.insert(0, g_data+sizeof(char), len); 
        return (std::string &)str; 
        } 
        
        int main(int argc, char* argv[]) 
        { 
        char ch='a'; 
        int num=10; 
        SetData<char>(0, ch); 
        SetData<int>(1,num); 
        
        printf("%c\n", GetData<char>(0)); 
        printf("%d\n", GetData<int>(1)); 
        
        char * str="test string!"; 
        SetData<char>(0, strlen(str)); 
        strcpy(g_data+1, str); 
        
        printf("%s\n", GetData<std::string>(0).c_str()); 
        return 0; 
        }

        예제 감사합니다.

        * 질문 : 인용할때 위에 원글 쓰신분 nickname을 어떻게 붙이나요?

        댓글 달기

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