#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; }
void show();
};
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;
memset(str, 0x00, sizeof(char) * (s.len + 1));
strcpy(str, s.str);
len = s.len;
}
string::~string()
{
std::cout << "[" << str << "]"
<< " - destructed" << std::endl;
if (str)
delete str;
}
void string::add_string(const string &s)
{
char *temp = new char[len + s.len + 1];
// 메모리를 강제 초기화, 가끔 쓰레기 데이터가 생기는 경우 있음
// 전체를 널로 초기화 하므로 배열/포인터 끝을 '\0' 처리할 필요없음
memset(temp, 0x00, sizeof(char) * (len + s.len + 1));
printf("add_string() - my len: [%d], s.len:[%d]\n", len, s.len);
// strcat을 직접 구현함
for (int i = 0; i < len; i++)
{
temp[i] = str[i];
}
for (int i = 0; i < s.len; i++)
{
temp[len + i] = s.str[i];
}
len += s.len;
delete[] str;
str = temp;
}
void string::copy_string(const string &s)
{
char *temp = new char[s.len + 1];
// 메모리를 강제 초기화, 가끔 쓰레기 데이터가 생기는 경우 있음
// 전체를 널로 초기화 하므로 배열/포인터 끝을 '\0' 처리할 필요없음
memset(temp, 0x00, sizeof(char) * (s.len + 1));
printf("copy_string() - my len: [%d], s.len:[%d]\n", len, s.len);
// strcpy를 직접 구현함
for (int i = 0; i < s.len; i++)
{
temp[i] = s.str[i];
}
len = s.len;
delete[] str;
str = temp;
}
void string::show()
{
printf("str(s): [%s]\n", str);
// printf("str(s+1): [%s]\n", str + sizeof(char));
printf("len: [%d]\n", len);
printf("str' address: %p\n", str);
// printf("len' address: %p\n", &len);
std::cout << std::endl;
}
int main()
{
string *s1 = new string('a', 10);
s1->show();
string *s2 = new string("Hello ");
s2->show();
string *s3 = new string(*s2);
s3->show();
string *s4 = s2;
s4->show();
string *s5 = new string("World");
s5->show();
std::cout << "------------------------" << std::endl;
s2->add_string(*s5);
s2->show();
s4->show();
std::cout << "------------------------" << std::endl;
s4->copy_string(*s5);
s4->show();
// 소멸자가 자동실행되지 않아서 강제 실행함
// s1->~string();
// s2->~string();
// s3->~string();
// // s4->~string(); // 얕은복사이므로 소멸자 호출하면 안된다.
// s5->~string();
return 0;
}
참고자료 : "모두의 코드" 사이트.
'C++' 카테고리의 다른 글
[C++] 상속(inheritance) - protected, private 키워드 (0) | 2023.02.16 |
---|---|
[C++] 상속(inheritance) (0) | 2023.02.16 |
[C++] 포인터 - 연산자 오버로딩(overloading) (0) | 2023.02.14 |
[C++] 포인터 - 얕은복사/깊은복사(샘플2) (0) | 2023.02.03 |
[C++] 포인터 - 얕은복사/깊은복사(샘플1) (0) | 2023.02.03 |