C++/모두의코드

4장 이어서..

twoweeks-within 2025. 1. 31. 21:04

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_;

 

'C++ > 모두의코드' 카테고리의 다른 글

7장  (0) 2025.02.04
6장  (0) 2025.02.02
5장 // 5.3 뒷부분은 복습때  (0) 2025.02.01
3장, 4장  (0) 2025.01.30
1장  (0) 2025.01.29