chapter 4. 객체 포인터와 객체 배열, 객체의 동적 생성

jisookim·2022년 5월 6일

c++

목록 보기
2/2

4.1 객체 포인터

객체를 다루기 위해 객체에 대한 포인터 변수를 선언!
이러한 포인터 변수로 객체의 멤버 변수를 읽고 값을 쓰거나 멤버 함수를 호출할 수 있다.

Circle donut;
double d = donut.getArea();

Circle *p;		// 객체에 대한 포인터 선언
p = &donut;		// 포인터에 객체 주소 저장
d = p->getArea();	// 맴버 함수 호출
  • 객체에 대한 포인터 변수 선언

  • 포인터 변수에 객체 주소 지정
    포인터 변수를 선언할 때 다음처럼 객체의 주소로 초기화 할 수도 있다.
    (초기화 하지 않은 객체 포인터를 이용하면 오류 발생 : null pointer assignment 발생. 왜냐하면 아무 객체도 가리키지 않고 있기 때문!)

    	Circle* p = &donut; // 포인터 변수 선언 시 객체 주소로 초기화 
  • 포인터를 이용한 객체 멤버 접근

4.2 객체 배열

  • 객체 배열 선언 및 활용
Circle circleArray[3]; 			//객체 배열 생성
circleArray[0].setRadius(10);
circleArray[1].setRadius(20);
circleArray[2].setRadius(30); 	//배열의 각 원소 객체의 맴버 접근
  • 객체 배열 선언문은 기본 생성자를 호출한다.
  • 점(.)연산자
  • 클래스의 포인터를 이용하여 배열을 다룰 수 있다.
  • 배열 소멸과 소멸자 : 배열이 소멸되면 모든 원소 객체마다 소멸자가 호출된다. 높은 인덱스에서부터 원소 객체 소멸, 맨 마지막에 클래스 소멸자 실행됨.
  • 객체 포인터를 사용하여 객체 배열을 다루는 다양한 사례 (165pg)
  • 객체 배열 초기화 : 객체 배열을 생성할 때 생성자를 사용하여 초기화 가능.
Circle circleArray[3] = {Circle(10), Circle(20), Circle()};
  • 다차원 객체 배열 (2차원, 3차원...)

4.3 동적 메모리 할당 및 반환

  • 동적 메모리 할당이 필요한 경우 : 실행 중에 필요한 만큼 메모리를 할당받고, 필요 없을 때 반환하는 '동적 메모리 할당/반환 메커니즘' 이 필요
  • new / delete
  • 힙(heap)이라는 공간으로부터 메모리 할당/반환.
  • new & delete 연산자 (c++ 기본 연산자)

    이제부터 중요한 것이니라.. 정신 차리시게..

  • new 와 delete의 기본 활용(170pg)
    -- <충!격!> 힙 메모리가 부족하면 new는 NULL을 리턴한다. 따라서, new의 리턴 값이 NULL인지 확인하는 것이 좋다.
    -- delete 후 포인터는 살아있지만, 해당 포인터가 가리키는 곳에 접근하면 안됨! (dangling pointer)
  • 동적 할당 메모리 초기화
    -- new 이용하여 메모리를 할당받을 때, '초기값'을 지정하여 초기화 할 수 있다.
    -- delete 사용시 주의사항
  • 배열의 동적 할당 및 반환
int *p = new int [5]; //크기가 5인 정수형 배열의 동적 할당
if (!p)
	return; //메모리 할당 실패시 p는 null을 반환하기에 먼저 검사
    
for (int i = 0; i < 5; i++)
	p[i] = i; // 배열에 순서대로 0 1 2 3 4 기록
    
delete [] p; // 배열 메모리 반환. 이때 포인터는 살아있다..! 
				이 포인터가 가리키는 곳에 더이상 접근하면 안됨.
  • 배열을 초기화 할 때 주의사항 : 직접 초기값 지정 불가능
    그러나 다음과 같이 초기값을 지정할 수 있음.
int *pArray = new int [] {1, 2, 3, 4}

배열일때만 delete [] q;
보통은 그냥 delete q;

4.4 객체와 객체 배열의 동적 생성 및 반환

  • 객체 배열의 동적 생성 및 반환
    동적으로 생성된 객체는 객체에 대한 포인터변수를 이용하여 반환.
delete 포인터변수;

<주의!!!> delete 사용 시, 포인터변수는 반드시 new를 이용하여 동적 할당받은 메모리의 주소여야 한다.
[잠깐!] Circle waffle; 과 Circle waffle()의 차이점(177pg)

Circle *pArray = new Circle[3]; // 3개의 Circle 객체 배열의 동적 생성
Circle *pArray = new Circle[3] {Circle(1), Circle(2), Circle(3)} // 3개의 Circle 객체를 반지름 1, 2, 3으로 각각 초기화
delete [] 포인터변수; // 포인터 변수가 가리키는 배열을 반환.
  • 동적으로 할당했으면 제발 반환하세요 ㅜ.ㅜ
  • [tip!] 동적 메모리 할당과 메모리 누수

4.5 this 포인터

  • this가 필요한 경우
    (1) 맴버 변수의 이름과 동일한 이름으로 매개 변수 이름을 짓기 위해
    (2) 객체의 멤버 함수에서 객체 자신의 주소를 리턴할 때. '연산자 중복' 때 많이 사용됨! (아니 연산자 중복 그게 뭔데~~ 기아악 7장에서 다시 정리하자.)

  • this 의 제약 조건
    (1) 클래스의 멤버 함수에서만 사용 가능
    (2) 멤버 함수라도 정적 멤버 함수 (static member function)은 this 사용 불가능... 정적 멤버 함수는 객체가 생성되기 전에 호출될 수 있으며, 정적 멤버 함수가 실행되는 시점에서 '현재 객체'는 존재하지 않을수 있기 때문. (static 멤버함수는 5장에서 다룸)

    (정적맴버함수에 대해 공부하고 나면 this 를 왜 쓰는지 알 수 있게 될것이다..!)
  • 컴파일러는 this를 어떻게 처리? (189pg)
    <<<<<<<<<정 리 필 요 ! >>>>>>>>>>>>

4.6 string 클라스를 이용한 문자열 사용

  • 기존의 c-스트링은 초기에 할당받은 메모리 크기 이상의 문자열을 저장할 수 없기 때문에 개발자의 프로그램 작성에 어려움이 있다.
  • 그러나 string 클래스는 문자열의 크기에 맞추어 스스로 메모리 크기를 조절하므로 사용하기 매우 편리하다!
  • string 객체 생성 및 출력
    (1) 객체 생성
    (2) 문자열 출력
    (3) 객체의 동적 생성
  • string 객체에 문자열 입력
  • 문자열 다루기
    stoi() 함수를 이용하면 문자열을 숫자로 변환할 수 있다.

0개의 댓글