Skip to content

Instantly share code, notes, and snippets.

@jjangga0214
Last active April 17, 2018 05:18
Show Gist options
  • Save jjangga0214/a1e4e99908850c8106fe3f7de93a370f to your computer and use it in GitHub Desktop.
Save jjangga0214/a1e4e99908850c8106fe3f7de93a370f to your computer and use it in GitHub Desktop.

두번째 실습 : class + 동적할당

mock.h

#ifndef XPP_MOCK_H
#define XPP_MOCK_H

#endif //XPP_MOCK_H

int sizeOfStr(const char str[]);

/**
 * Thread Non-Safe
 * Mutable => String 은 Immutable 하게 구현하는 것이 좋다.
 * Not Cached in inner Map
 *      => 만일 특정 종류의 문자열을 여러번 다루는 경우, 생성자를 private 으로 감추고
 *      팩토리 패턴으로만 인스턴스를 생성하면서 
 *      내부에서 이미 동등한 인스턴스가 존재하는지 cache 를 검사하게 할 수도 있다.
 */
class MyDynamicString {
private:
    char *memory;

public:

    //동적할당이 아니고 immutable 하게 한다면 이것도 가능하다.
    //MyDynamicString(char str[] = "") : memory(str) {} 

    MyDynamicString(char str[] = ""){
        int len = sizeOfStr(str);
        memory = new char[len]();
        for (int i = 0; i < len; ++i) {
            memory[i] =  str[i];
        }
    }

    /**
     * @return dynamic 하게 계산된 길이
     * 매번 loop 를 돌면서 계산하는 것 말고, 길이가 바뀔때마다 길이 필드를 update 하는 것이 더 좋을 수 있다.
     */
    int size() {
        return sizeOfStr(memory);
    }

    void cpy(const char str[]) {
        int len = sizeOfStr(str);
        char *temp = new char[len]();

        for (int j = 0; j < len; ++j) {
            temp[j] = str[j];
        }
        /*
         * 실증용 : 기본 타입의 배열이므로 free 도 작동한다.
         * 원칙적으로는 new operator 생성되거나, 또는 사용자 정의 객체인경우 delete 를 쓴다.
         * 간단히 말하면, 가능한 한 malloc -> free, new -> delete
         */ 
        free(memory); 
        memory = temp;
    }

    void cat(const char str[]) {
        const int strLen = sizeOfStr(str);
        const int oldMemoryLen = size();

        //const 가 앞에 있으므로, 포인터가 const 인 것이 아니고, 포인터가 가리키는 곳을 const로 취급
        const char *temp = memory;

        char *concatenated = new char[oldMemoryLen + strLen]();

        for (int j = 0; j < oldMemoryLen; ++j) {
            //concatenated[j] = memory[j]; // => 이것도 가능.
            concatenated[j] = *(temp++); // => 이것도 가능. 그냥 포인터로 해봤다.
        }

        for (int i = 0; i < strLen; ++i) {
            concatenated[oldMemoryLen + i] = str[i];
        }

        delete [] memory;
        memory = concatenated;
    }

    int cmp(const char str[]) {
        char *temp = memory;
        int i;
        for (i = 0; i < size(); ++i, temp++) {
            if (str[i] != *temp) {
                return *temp - str[i] > 0 ? 1 : -1;
            }
        }
        return str[i] == '\0' ? 0 : 1; //str 의 크기가 memory의 크기 초과이면 1을 반환
    }

    std::string tostring() {
        return memory;
    }
};


int sizeOfStr(const char str[]) {
    int counter = 0;
    const char *m = str;
    while (*(m++) != '\0') {
        counter++;
    }

    return counter;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment