1. 레퍼런스함수의 리턴 > 레퍼런스
int& ref();
>
int& rev = ref();
ref() = 3;
>> 레퍼런스로 값 복사 or 레퍼런스처럼 값지정
2.
marine2.be_attacked(marine1.attack()).be_attacked(marine1.attack());
1. marine2.be_attacked(marine1.attack()) > return *this
2. marine2.be_attacked(marine1.attack())
> 앞에 거 하고 리턴 > 뒤에거
Marine& ~~~(){
return *this;
}
// 기존의 Marine을 가져옴
<>
Marine ~~~() { return *this;}// 새로운 Marine을 생성해서 그걸 복사해옴
3. const함수 : 다른 변수의 값을 바꾸지 않는 함수
> 상수 변수를 읽는용
선언)
Type name(); const
// int marine(); const
구현)
Type name(); const { return a; }// int marine(); const { return a; }
4. 모든 멤버를 private > int get_x() { return x; } 과 같은 함수들로 변수 접근
5. string 클래스 구현
재료)
1) 공간을 가르키는 포인터
2) 데이터의 길이
> 길이만 알면 끝에 NULL 이 굳이 없어도
3) 메모리의 크기
> assign 등을 할때 재할당 할지말지
> 할당 후 문자열길이를 메모리 케페시터로 저장
> assign 할때 그것보다 긴경우에만 delete[] 후 새로 new
6. assign함수
EX)
MyString str1("very very very long string");
str1.assign("short string");
str1.assign("very long string");
st1 을 지정, 재지정 할 수 있음
7. insert 함수
: 문자열 중간에 삽입
MyString& MyString::insert(int loc, const MyString& str);
MyString& MyString::insert(int loc, const char* str);
MyString& MyString::insert(int loc, char c);
>
MyString& MyString::insert(int loc, const MyString& str) {
// 이는 i 의 위치 바로 앞에 문자를 삽입하게 된다. 예를 들어서
// abc 라는 문자열에 insert(1, "d") 를 하게 된다면 adbc 가 된다.
// 범위를 벗어나는 입력에 대해서는 삽입을 수행하지 않는다.
if (loc < 0 || loc > string_length) return *this;
if (string_length + str.string_length > memory_capacity) {
// 이제 새롭게 동적으로 할당을 해야 한다.
memory_capacity = string_length + str.string_length;
char* prev_string_content = string_content;
string_content = new char[memory_capacity];
// 기존 + 신규를 합친 메모리할당
// 일단 insert 되는 부분 직전까지의 내용을 복사한다.
int i;
for (i = 0; i < loc; i++) {
string_content[i] = prev_string_content[i];
}
// 그리고 새롭에 insert 되는 문자열을 넣는다.
for (int j = 0; j != str.string_length; j++) {
string_content[i + j] = str.string_content[j];
}
// 이제 다시 원 문자열의 나머지 뒷부분을 복사한다.
for (; i < string_length; i++) {
string_content[str.string_length + i] = prev_string_content[i];
}
delete[] prev_string_content;
string_length = string_length + str.string_length;
return *this;
}
// 만일 초과하지 않는 경우 굳이 동적할당을 할 필요가 없게 된다.
// 효율적으로 insert 하기 위해, 밀리는 부분을 먼저 뒤로 밀어버린다.
for (int i = string_length - 1; i >= loc; i--) {
// 뒤로 밀기. 이 때 원래의 문자열 데이터가 사라지지 않게 함
string_content[i + str.string_length] = string_content[i];
}
// 그리고 insert 되는 문자 다시 집어넣기
for (int i = 0; i < str.string_length; i++)
string_content[i + loc] = str.string_content[i];
string_length = string_length + str.string_length;
return *this;
}
>>
string_length 의 중요성!!
> 배열의 종점을 알려줌
> for 문 등을 사용할때 다른 배열과 연결시 기점 정하기 용이
// 끝은 시작이기도 하니깐..
응용
만약 1~2글자씩 조금씩 자주 계속 insert 한다면..
> 할당/해제/할당/해제.. > 낭비 심함
>> 캐페시터를 넉넉히 잡아두자
if (string_length + str.string_length > memory_capacity) {
// 이제 새롭게 동적으로 할당을 해야 한다.
if (memory_capacity * 2 > string_length + str.string_length)
memory_capacity *= 2;
else
memory_capacity = string_length + str.string_length;
캐페시터를 2배 정도 넉넉히 잡아두기 , 애초에 크게 들어온거면 그냥 수용
delete 함수
: 몇번째, 얼마나를 인자로 받아서
for (int i = loc + num; i < string_length; i++) {
string_content[i - num] = string_content[i];
}
몇번째 > 기점 // i - num
몇번째 + 얼마나 > 종점 // i
> 종점부터의 문자들을 기점부터 넣어줌 > 기존문자는 덮여씌여짐
Find 함수
int MyString::find(int find_from, const MyString& str) const {
int i, j;
if (str.string_length == 0) return -1;
for (i = find_from; i <= string_length - str.string_length; i++) {
for (j = 0; j < str.string_length; j++) {
if (string_content[i + j] != str.string_content[j]) break;
}
if (j == str.string_length) return i;
}
return -1; // 찾지 못했음
}
ex) find_from 번째의 글자 수 부터 str로 받은 문자열이 몇번째에 있는지 리턴
첫번째 for ) 앞글자만 확인하면 되므로, 전체문자-입력문자 받은만큼만 확인
두번째 for ) 첫번째 글자부터 끝글자 까지 같지 않다면 break;
compare 함수
for (int i = 0; i < std::min(string_length, str.string_length); i++) {
if (string_content[i] > str.string_content[i])
return 1;
else if (string_content[i] < str.string_content[i])
return -1;
}
min : 둘중 작은 놈을 반환
> abcd, abcdef 가 있으면 일단 abcd 까지만 비교
explicit
explicit MyString(int capacity);
컴파일러가 암시적 변환 못하게함
// 꼭 int형을 넣어줘야함 ( 명시적 )
mutable
: const 함수 내에서도 값 변경 가능
mutable int data_;