본문 바로가기

C++

[C++] 포인터 - 얕은복사/깊은복사(샘플2)

포인터의 개념중에서 얕은복사, 깊은 복사에 대한 추가 샘플 코드입니다.

 

 

#include <iostream>

class string
{
    char *str;
    int len;

public:
    string(char c, int n); // 문자 c 가 n 개 있는 문자열로 정의
    string(const char *s);
    string(const string &s);
    ~string();

    void add_string(const string &s);  // str 뒤에 s 를 붙인다.
    void copy_string(const string &s); // str 에 s 를 복사한다.
    int strlen();
    int GetLen() { return len; }
    char *GetStr() { return str; }
    // 문자열 길이 리턴
};

int string::strlen()
{
    int len = 0;
    while (str[len] != '\0')
    {
        len++;
    }
    return len;
}

string::string(char c, int n)
{
    std::cout << "생성자(string(char c, int n))" << std::endl;
    str = new char[n];
    for (len = 0; len < n; len++)
    {
        str[len] = c;
    }
    str[len] = '\0';
}

string::string(const char *s)
{
    std::cout << "생성자(string(const char *s))" << std::endl;
    len = 0;
    while (s[len])
    {
        len++;
    }

    str = new char[len + 1];
    memset(str, 0x00, sizeof(char) * (len + 1));
    strcpy(str, s);
}

string::string(const string &s)
{
    std::cout << "생성자(복사생성자)" << std::endl;
    str = new char[s.len + 1];
    str = s.str;
    // strcpy(str, s.str);
    // len = s.len;
}

string::~string()
{
    std::cout << "[" << str << "]"
              << " - destructed" << std::endl;
    delete[] str;
}

void string::add_string(const string &s)
{
}

void string::copy_string(const string &s)
{
}

int main()
{
    std::cout << std::endl;
    string *s1 = new string('a', 5);
    printf("s1: [%s]\n", s1->GetStr());
    printf("s1: [%p]\n", s1->GetStr());
    printf("s1's length: %d\n", s1->GetLen());
    printf("s1's length: %d\n", s1->strlen());

    std::cout << std::endl;
    string *s2 = new string("this is c/c++");
    printf("s2: [%s]\n", s2->GetStr());
    printf("s2' 5th: [%s]\n", s2->GetStr() + sizeof(char) * 5);
    printf("s2:       [%p]\n", s2->GetStr());
    printf("s2's 5th: [%p]\n", s2->GetStr() + sizeof(char) * 5);
    printf("s2's length: %d\n", s2->GetLen());
    printf("s2's length: %d\n", s2->strlen());

    std::cout << std::endl;
    string *s3 = new string(*s2);
    printf("s3: [%s]\n", s3->GetStr());
    printf("s3: [%p]\n", s3->GetStr());
    printf("s3's length: %d\n", s3->GetLen());
    printf("s3's length: %d\n", s3->strlen());

    return 0;
}

 

복사 생성자에 대한 부분은 아래와 같습니다. 이번에는 얕은 복사 샘플 코드입니다.

 

string::string(const string &s)
{
    std::cout << "생성자(복사생성자)" << std::endl;
    str = new char[s.len + 1];
    str = s.str;
    // strcpy(str, s.str);
    // len = s.len;
}

 

복사생성자에서 생성된 메모리는 2번째 인스턴스의 메모리와 동일한 주소([0x60000066c070])를 참조한다.

 

 

 

이번에는 깊은 복사 샘플 코드로 변경해 보고 테스트해보겠습니다. 메모리 참조위치가 각각 다른것을 볼 수 있다.

 

string::string(const string &s)
{
    std::cout << "생성자(복사생성자)" << std::endl;
    str = new char[s.len + 1];
    // str = s.str;
    strcpy(str, s.str);
    len = s.len;
}

 

 

 

 

 

 

 

참고자료 : "모두의 코드" 사이트.