C++
[C++] MyString 클래스 실습
mintuchel
2023. 4. 13. 22:42
1. 포인터 받을때 nullptr 항상 체크해주기
2. int 같은거 받을때 0 항상 체크
3. 왜 getLength(const char* in) 은 static인지 이유 알기
int MyString::getLength(const char* in) {
if (in == nullptr) return 0; // important
int ret = 0;
while (*in++ != NULL) ret++;
return ret;
}
getLength 함수는 해당 클래스 내 멤버변수를 참조하여 사용하진 않지만
해당 클래스 객체가 사용할 목적으로 정의한 함수이다.
따라서 static으로 클래스 내부에 넣어두는게 좋다
왜냐하면 만약 static이 아니면 이 함수 하나 호출하기 위해
불필요한 객체를 생성해야하기 때문이다! (???? 솔까 ㅈㄴ 이상함 이게 이유가 말이 안됨)
4. 왜 operator << 는 friend 인지 알아놓기
5. 왜 append는 참조형 반환이 안되는지 알아놓기
const MyString& operator+(const MyString& in) { // 이건 reference 붙이면 안됨 이유는?
// reference로 넘기면 안되는 이유는
// 이 함수가 끝나면
MyString out = *this;
out.append(in);
return out;
// 이 로컬변수 out은 해제되기 때문임!
// 만약 reference로 넘기고 싶으면
// MyString* out = new MyString(*this);
// out->append(int);
// return *out;
// 이렇게 포인터로 외부변수로 해줘야함!
// 여기서는 그냥 reference로 안넘기는 방법을 제시
// const MyString 이렇게 reference로 넘기지 말자
}
6. 동적할당이면 무조건 복사생성자 직접 정의 ( 얕은 복사로 안되기 때문 )
직접 정의해줘 깊은 복사 하게 만들어야함!
7. 언제 operator를 멤버함수로 해야하는지 외부함수로 해야하는지 알기
8. const 선언 이해
ostream& operator<<(ostream& os, const MyString& in) {
if (in.m_pStr==nullptr || in.getLength() == 0) return os; // const 선언이면 함수사용은 노빠꾸로 제한함
// const는 data type 선언할때, 함수 선언, 참조자 선언할때 쓰임
// const 함수는 변하지 않게 한다는것
// 그래서 const 함수에서 const 변수를 부르는건 안전하다
// 만약 getLength()에 const가 없으면 에러가 난다
os << in.m_pStr;
return os;
}
9. 대입연산자 자기자신 받을떄 예외처리 ㅈㄴ 중요
const MyString& MyString::operator=(const MyString& in) {
// 같은 놈인지 확인 이거 중요 a=a이면 아래 코드 진행하면 a 데이터만 다 날라가는 ㅈ되는 상황
if (this == &in) {
return *this;
}
releaseMemory();
m_length = in.getLength(); // length 받고
if (m_length == 0) return *this;
assignMemory(); // 초기화
}
[MyString.h]
#ifndef __MYSTRING_H__
#define __MYSTRING_H__
#include <iostream>
class MyString
{
private:
char* m_pStr;
int m_length;
public:
MyString();
MyString(const char* in);
MyString(const MyString& in); // copy constructor (복사생성자)
~MyString(); // destructor (소멸자)
void assignMemory();
void releaseMemory();
int getLength() const {return m_length; }
static int getLength(const char* in, int max_length=255);
// cout<< overload
// 내 객체가 오른쪽에 와야하니까 전역함수로 구현하고 friend 선언
// const는 상수로 받는다는 것 왜? 바꿀 이유가 없으니
friend std::ostream& operator<<(std::ostream& o, MyString& in);
// 대입연산자 assignment operator
// 항상 왼쪽은 우리꺼 오른쪽은 MyString 타입
// 클래스 내 멤버함수로 정의해도 가능
const MyString & operator=(const MyString& in);
const MyString operator+(const MyString& in);
void append(const MyString& in);
};
#endif
[MyString.c]
#include "MyString.h"
MyString::MyString()
{
m_pStr = nullptr;
m_length = 0;
}
MyString::MyString(const char* in)
{
m_length = getLength(in);
m_pStr = nullptr;
if (m_length == 0) return;
assignMevd5mory();
for (int i = 0; i < m_length; i++)
m_pStr[i] = in[i];
m_pStr[m_length] = '\0';
}
MyString::MyString(const MyString& in)
{
/*
m_pStr = nullptr;
m_length = 0;
*this = in;
*/
m_pStr = nullptr;
m_length = in.getLength();
if (m_length == 0) return;
assignMemory();
for (int i = 0; i < m_length; i++)
m_pStr[i] = in.m_pStr[i];
m_pStr[m_length] = '\0';
}
// a = a
const MyString& MyString::operator=(const MyString& in)
{
if (this == &in) return *this;
releaseMemory();
m_length = in.getLength();
if (m_length == 0) return *this;
m_pStr = new char[m_length + 1];
for (int i = 0; i < m_length; i++)
m_pStr[i] = in.m_pStr[i];
m_pStr[m_length] = '\0';
return *this;
}
MyString::~MyString()
{
releaseMemory();
}
void MyString::assignMemory()
{
if (m_length == 0) return;
m_pStr = new char[m_length + 1];
}
void MyString::releaseMemory()
{
if (m_pStr != nullptr)
delete[] m_pStr;
m_pStr = nullptr;
m_length = 0;
}
int MyString::getLength(const char* in, int max_length)
{
if (in == nullptr) return 0;
int leng = 0;
while (true)
{
if (in[leng] == '\0') return leng;
if (leng >= max_length) return leng;
leng++;
}
}
std::ostream& operator<<(std::ostream& o, MyString& in)
{
if (in.m_pStr == nullptr || in.getLength() == 0) return o;
o << in.m_pStr;
return o;
}
void MyString::append(const MyString& in)
{
if (in.getLength() == 0) return;
MyString temp = *this;
if (m_length > 0) releaseMemory();
m_length = temp.getLength() + in.getLength();
assignMemory();
for (int i = 0; i < temp.m_length; i++)
m_pStr[i] = temp.m_pStr[i];
for (int i = 0; i < in.m_length; i++)
m_pStr[i + temp.m_length] = in.m_pStr[i];
m_pStr[m_length] = '\0';
}
const MyString MyString::operator+(const MyString& in)
{
MyString out(*this);
out.append(in);
return out;
}