Skip to content

Instantly share code, notes, and snippets.

@jjangga0214
Last active April 19, 2018 05:28
Show Gist options
  • Save jjangga0214/39858a75e3fdc17d8fa301f02300c3c0 to your computer and use it in GitHub Desktop.
Save jjangga0214/39858a75e3fdc17d8fa301f02300c3c0 to your computer and use it in GitHub Desktop.

실습 3

mock.h

#ifndef XPP_MOCK_H
#define XPP_MOCK_H


#include <cstring>

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];
        }
    }

    MyDynamicString(const MyDynamicString& other){
        cpy(other.memory, false);
    }

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

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

        for (int j = 0; j < len; ++j) {
            temp[j] = str[j];
        }

        if(deleting){
            /*
            * 실증용 : 기본 타입의 배열이므로 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;
    }

    ~MyDynamicString() {
        delete[] memory;
    }
};


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

    return counter;
}


#endif //XPP_MOCK_H

main.cpp

#include <iostream>
#include "mock.h"

using namespace std;

int main() {

    MyDynamicString s2("abcde"); //abcde
    MyDynamicString s3(s2); //abcde
    cout<<s2.tostring()<<'\n'; //abcde 출력
    cout<<s2.size()<<'\n'; //5 출력

    cout<<s3.tostring()<<'\n'; //abcde 출력
    cout<<s3.size()<<'\n'; //5 출력

    s2.cat("fg");//abcdefg
    cout<<s2.tostring()<<'\n';//abcdefg 출력
    cout<<s2.size()<<'\n';// 7출력

    cout<<s3.tostring()<<'\n'; //abcde 출력
    cout<<s3.size()<<'\n'; //5 출력

    cout<<s2.cmp("abced")<<'\n';// -1 출력
    cout<<s2.cmp("abcdefg")<<'\n';// 0 출력
    cout<<s2.cmp("abcdefg0")<<'\n';// 1 출력

    s2.cpy("hello there");
    cout<<s2.tostring()<<'\n';// hello there 출력
    cout<<s2.size()<<'\n';// 7출력

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