devRenio

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

객체지향프로그래밍II(김정준) 중간고사 대비 (4장)

객체 포인터

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

Circle *p;
p = &donut; // 객체에 대한 포인터 선언
area = p->getArea(); // 멤버 함수 호출
area = (*p).getArea(); // 멤버 함수 호출
  • 객체에 대한 포인터
    • 객체의 주소 값을 가지는 변수
  • 포인터로 멤버를 접근할 때
    • 객체포인터->멤버

Circle circleArray[3]; // Circle 객체 배열 생성
Circle circleArray[3](5); // 오류 (매개변수 있는 생성자 호출 불가)

circleArray[0].setRadius(10); // 객체 배열의 원소 객체 멤버 접근

Circle *p = circleArray; // p == circleArray[0]
p++; // p == circleArray[1]

객체 배열

  • 객체 배열 선언 가능
    • 기본 타입 배열 선언과 형식 동일
    • n차원 배열도 선언 가능
  • 객체 배열 선언
    1 객체 배열을 위한 공간 할당
    2 배열의 각 원소 객체마다 생성자 실행
    • 매개 변수 없는 생성자 호출
  • 매개 변수 있는 생성자를 호출할 수 없음
    • 기본 생성자가 없는 클래스에서 객체 배열 선언시 오류 발생
  • 배열 소멸
    • 배열의 각 객체마다 소멸자 호출. 생성의 반대순으로 소멸

객체 배열 초기화

// 각 원소별로 생성자 지정 가능
Circle circleArray[3] = { Circle(10), Circle(20), Circle() }


동적 메모리 할당 및 반환

  • 정적 할당
    • 변수/배열 선언을 통해 필요한 메모리 할당
  • 동적 할당
    • 필요한 양이 예측되지 않는 경우. 프로그램 작성시 할당 받을 수 없음
    • 실행 중에 힙(heap, 동적 할당 공간) 메모리에서 할당
  • C++의 동적 메모리 할당/반환
    • new 연산자
      ◼ 기본 타입 메모리 할당, 배열 할당, 객체 할당, 객체 배열 할당
      ◼ 객체의 동적 생성 - 힙 메모리로부터 객체를 위한 메모리 할당 요청
      ◼ new 데이터타입(초깃값)으로 초기화 가능
      ◼ 객체 할당 시 생성자 호출
      ◼ 할당 실패 시 NULL 반환
    • delete 연산자
      ◼ new로 할당 받은 메모리 반환
      ◼ 객체의 동적 소멸 - 소멸자 호출 뒤 객체를 힙에 반환
      ◼ delete 후에도 할당받은 포인터 변수는 생존하지만 접근하면 오류 발생
      ◼ 동적으로 할당받지 않은 메모리를 반환하면 오류 발생
      ◼ 동일한 메모리를 여러 번 반환하면 오류 발생
    • 동적으로 할당된 메모리를 반환하지 않고 포인터를 변경한다면 메모리 누수 발생
    • 프로그램 종료 시 운영체제가 누수 메모리를 모두 힙에 반환
char *pChar = new char; // char 타입의 메모리 동적 할당
int *pInt = new int(20); // int 타입의 메모리 동적 할당, 20으로 초기화
Circle *pCircle = new Circle(); // Circle 클래스 타입의 메모리 동적 할당
Circle *pCircle = new Circle(20); // 매개변수가 있는 생성자 호출

delete pChar; // 할당 받은 문자 공간 반환
delete pInt; // 할당 받은 정수 공간 반환
delete pCircle; // 할당 받은 객체 공간 반환


배열의 동적 할당 및 반환

int *p = new int[n]; // n개의 정수 배열 동적 할당
int *pp = new int[n](20); // 오류. 배열은 동적 할당 시 초기화 불가능
Circle *pArray = new Circle[n]; // 각 원소 객체의 기본 생성자 Circle() 실행

p[0] = 5; // 동적 할당된 배열 원소에 접근

delete [] p; // 배열 메모리 반환
delete pp;// []를 생략해도 오류는 아니지만 비정상적인 반환
delete [] pArray; // 각 원소 객체의 소멸자 ~Circle() 실행


this 포인터

class Circle{
  int radius;
public:
  Circle() { this->radius = 1; } // 컴파일러에 의해 삽입
  Circle(int radius) { this->radius = radius; }
  Circle* testFunc() { return this; } // 객체가 자신의 주소를 반환
  ...
}
  • 객체 자신을 가리키는 포인터
  • 클래스의 멤버 함수 내에서만 사용
  • 멤버 함수에 컴파일러에 의해 묵시적으로 삽입 선언되는 매개 변수
  • 매개변수의 이름과 멤버 변수의 이름이 같은 경우(위 예제의 radius)에 필요
  • 멤버 함수가 객체 자신의 주소를 리턴할 때 필요 (연산자 중복 시 매우 필요)

this의 제약 사항

  • 멤버 함수가 아닌 함수에서 사용 불가
  • static 멤버 함수에서 this 사용 불가
    • 객체가 생성되기 전에 static 함수 호출이 가능하기 때문

this의 실체

// 컴파일러에 의해 묵시적으로 this 매개변수 삽입
Circle(Circle* this) { this->radius = 1; }
...
Circle donut;
donut.setRadius(&donut, 10); // 컴파일러에 의해 자신의 주소를 매개변수로 전달


string 클래스

  • C++ 문자열
    • C-스트링
    • C++ string 클래스의 객체
  • string 클래스
    • C++ 표준 라이브러리, <string> 헤더 파일에 선언
    • 가변 크기의 문자열
    • 다양한 문자열 연산을 실행하는 연산자와 멤버 함수 포함
      ◼ 문자열 복사, 문자열 비교, 문자열 길이 등
    • 문자열, 스트링, 문자열 객체, string 객체 등으로 혼용