Skip to content

Instantly share code, notes, and snippets.

@jjangga0214
Last active May 3, 2018 05:32
Show Gist options
  • Save jjangga0214/4dd5c7cbe781befb89be39909a861b1b to your computer and use it in GitHub Desktop.
Save jjangga0214/4dd5c7cbe781befb89be39909a861b1b to your computer and use it in GitHub Desktop.
c++ 실습 4

실습 4

mystring.h

#ifndef XPP_MYSTRING_H
#define XPP_MYSTRING_H

#include <cstring>
#include <cstdlib>
#include <string>

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[] = "");

    MyDynamicString(const MyDynamicString &other);

    MyDynamicString &operator=(MyDynamicString &other);

    friend std::ostream& operator<<(std::ostream &os, MyDynamicString &myDynamicString);

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

    int size() const{
        return sizeOfStr(memory);
    }

    void cpy(const char str[], bool deleting = true);

public:

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

    MyDynamicString(char str[] = "");

    MyDynamicString(const MyDynamicString &other);

    MyDynamicString &operator=(const MyDynamicString &other);

    friend std::ostream& operator<<(std::ostream &os, const MyDynamicString &myDynamicString);

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

    int size() const{
        return sizeOfStr(memory);
    }

    void cpy(const char str[], const bool deleting = true);

    void cat(const char str[]);

    int cmp(const char str[]) const;

    std::string tostring() const{
        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

mystring.cpp

#include "mystring.h"


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

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

MyDynamicString &MyDynamicString::operator=(const MyDynamicString &other) {
    cpy(other.memory, false);
    return *this;
}

std::ostream& operator<<(std::ostream &os, const MyDynamicString &myDynamicString){
    os<<myDynamicString.tostring()<<'\n';
    return os;
}

void MyDynamicString::cpy(const char str[], const bool deleting) {
    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 MyDynamicString::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 MyDynamicString::cmp(const char str[]) const{
    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을 반환
}
P.S main 은 생략한다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment