[ 공 부 ]/[ C + + ]
[ C++ ] STRING Class
HiStar__
2019. 11. 13. 01:09
문 제
-
간단하게 String Class 구현
소 스 코 드
// class(struct) 키워드로 사용자 정의 자료형을 만든다.
// - 생성시 자원을 할당하였다면 ( 자원을 사용하지 않는다면 아무것도 할 필요 없다. )
// 1. 소멸자에서 자원 해제
// 2. 깊은 복사를 코딩 해야 한다.
// 3. 2번과 쌍인 Copy Assignment를 제대로 코딩해야 한다.
//
// 4. 최신 이동기능을 지원하려면 이동생성자를 코딩
// 5. 4와 한 쌍인 이동할당연산자를 코딩해야 한다.
////////////////////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <random>
#include <algorithm>
#include "SaveCode.h"
std::default_random_engine dre;
std::uniform_int_distribution<> uidINT{ 1 ,70 };
std::uniform_int_distribution<> uidCHAR{ 'a', 'z' };
class STRING {
char *word;
size_t length; // 저장한 글자수
public:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// STRING() : word{ nullptr }, length{ 0 } {}
STRING() {
length = uidINT(dre);
word = new char[length];
for (int i = 0; i < length; ++i) {
word[i] = uidCHAR(dre);
}
}
~STRING() { if(word != nullptr) delete[] word; } // 생성자에서 확보한 자원은 객체가 사라질 때 정리해야!
STRING(const char* w) {
length = strlen(w);
word = new char[length];
memcpy(word, w, length);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 복사 생성자( 생성자에서 자원을 할당한 경우 )
STRING(const STRING& other) : length{ other.length } {
word = new char[length];
// 깊은 복사의 경우 strcpy가 아니라 memcpy를 사용한다.
// strcpy(word, other.word);
memcpy(word, other.word, length);
}
// CopyAssignment 복사할당 연산자 b = a;
STRING& operator=(const STRING & other) {
if (this == &other) return *this; // 예외문 a = a; 무의미한 할당하는 행동을 제하는 코드
if (length != 0) delete[] word;
length = other.length;
word = new char[length];
// 깊은 복사가 많이 생긴다면,
// *this = other; // memcpy 대신 사용을 한다.
memcpy(word, other.word, length); //
return *this;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 자원을 이동하고 싶으면 (선택 사항)
// 이동은 데이터 안정성 측면에서 위험할 수 있기 때문에
// 안전하다는 보증을 프로그래머가 직접 해줘야함.
// noexcept : 이 함수는 안정된 함 수 이다.
//
// && 아벨류 레퍼런스
STRING(STRING&& other) noexcept : length{ other.length }, word{ other.word } {
// 이동 대상의 멤버를 잘 정리
other.word = nullptr;
other.length = 0;
}
// 이동 할당 연산자 move assignment
STRING operator=(STRING&& other) noexcept {
// 나를 나에게 할당 되지 않게
if (this != &other) return *this;
// 내가 잡은 메모리가 있다면 해제
if (length != 0) delete[] word;
// ohter의 자원을 가져오기
word = other.word;
length = other.length;
other.length = 0;
other.word = nullptr;
return *this;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// + 함수
// 주의 임시 변수 이기 때문에
// STRING &의 경우 메모리 주소를 가져오는 것이기 때문에 지역변수의 경우 삭제가 됨으로 제대로 된 값을 받을 수 없다.
// const STRING &other 의 경우 인자 값이 변하지 않음 ) const { 나 자신도 변하지 않음.
STRING operator+(const STRING & other) const {
STRING stemp;
stemp.length = length + other.length;
stemp.word = new char[stemp.length];
memcpy(stemp.word, word, length);
memcpy(stemp.word + length, other.word, other.length);
return stemp;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// [] 함수
// 읽기 전용
char operator [](const int& idx) const {
if (length < idx) exit(1);
else return *(word + idx);
}
// 쓰기 전용
// char& 나 자신
char& operator [](int idx) {
return *(word + idx);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 범위 기반 for 루프를 위한 코드
char* begin() const {
return word;
}
char* end() const {
return word + length;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
int GetLength()const { return length; }
// ostream 입출력 연산자
friend std::ostream& operator << (std::ostream&, const STRING&);
};
std::ostream& operator << (std::ostream& os, const STRING& rhs) {
os << "길이 : " << rhs.length << "\t";
for (int i = 0; i < rhs.length; ++i) {
os << rhs.word[i];
}
return os;
}
// [문제] STRING을 100개를 생성하라
// 각 STRING의 길이를 random(1 ~ 70) , 각 글자를 random(a ~ z) 하게 만들어라.
// 전체 STRING을 길이 오름차순으로 정렬하라.
// 전체를 출력하라.
int main() {
// CodeSave("Main.cpp"); // 코드 저장용 함수
// 생성자로 만들기
STRING random[100];
std::sort(std::begin(random), std::end(random), [](const STRING& a, const STRING& b) {return a.GetLength() > b.GetLength(); });
for (const auto &a : random) {
std::cout << a << std::endl;
}
return 0;
}