-
[C++] MyString 클래스 실습C++ 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; }
'C++' 카테고리의 다른 글
[C++] default parameter (1) 2023.04.19 [C++] 반환형 참조형 (return값이 참조형일때) (0) 2023.04.15 [C++] const (1) 2023.04.12 [C++] 접근지정자 (access modifiers) (3) 2023.04.11 [C++] friend (2) 2023.04.11