04. 포인터, 동적 할당

4.1 객체 포인터

포인터 : 변수의 메모리 공간의 주소를 가리키는 변수를 말한다.

p = &donut;         //p에 donut 객체의 주소 저장
Cricle* p = &donut; //포인터에 변수 선언 시 객체 주소롤 초기화
d = p->getArea(); 
// 또는
d = (*p).getArea(); //포인터로 객체 멤버 함수 호출
// <=> d = donut.getArea() 객체 이름으로 멤버 함수 호출

4.3 동적 메모리 할당 및 반환

동적 메모리 할당

실행 중에 필요한 만큼 메모리를 할당받고 필요 없을 때 메모리를 반환한다. 데이터타입 *포인터변수 = new 데이터타입

  • C++에선 newdelete 연산자를 이용한다.
  • new : heap에서 메모리를 할당받고
  • delete : 메모리를 heap으로 반환한다
int *pInt = new int; 
char *pChar = new char;
delete pInt;	     
delete pChar;

Int *p = new int;   //힙으로부터 int 타입의 정수 공간 할당
If(!p){             //p가 null이면 메모리 할당받기 실패
    Return
}
*p = 5;		        //할당받은 정수 공간에 5기록
Int n = *p;	        //할당받은 정수 공간에서 값 읽기 n=5
delete p;	        //할당받은 정수 공간 반환


동적 할당 메모리 초기화

new를 이용하여 메모리를 할당받을 때 초기값을 지정하여 초기화 가능
데이터타입 *포인터변수 = new 데이터타입(초기값)

int *pInt = new int(20);
char *pChar = new char(a);


배열의 동적 할당 및 반환

데이터타입 *포인터변수 = new 데이터타입 [배열의 크기]; 배열의 동적 할당
delete [] 포인터변수; 배열 메모리 반환

int *p = new int[5];                //크기가 5인 정수형 배열의 동적 할당
int *pArray = new int [] {1,2,3,4}  //1,2,3,4로 초기화된 정수 배열 생성
delete [] p;
delete [] pArray;

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

객체의 동적 생성 및 반환

클래스이름 *포인터변수 = new 이름(생성자매개변수리스트);
new는 클래스 크기를 메모리를 할당받아 객체를 생성하며 이때 생성자를 호출한다. delete는 동적으로 생성된 객체를 반환다는 것이다.

Circle *p = new Circle;     //기본 생성자 Circle() 호출
Circle *q = new Circle(30); //생성자 Circle(30) 호출
delete p;                   //Circle 객체 반환
delete q;                   //Circle 객체 반환


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

클래스이름 *포인터변수 = new 클래스이름 [배열크기];
delete [] 포인터변수

Circle *pArray = new Circle[3];
//배열 원소 초기화
Circle *pArray = new Circle[3] {Circle(1), Circle(2), Circle(3)};
delete [] pArray;
//배열 반환시 pArray[2] -> pArray[1] -> pArray[0] 순으로 소멸자가 실행된다.

4.5 this 포인터

this : 자신에 대한 포인터로서 클래스 멤버 함수 내에서만 사용된다. 전역 변수도 아니고 함수 내 선언된 지역 변수도 아니다. 객체의 멤버 함수가 호출될 때 컴파일러에 의해 보이지 않게 전달되는 객체에 대한 주소이다.

this가 필요한 경우

  1. 멤버 변수의 이름과 동일한 이름으로 매개 변수 이름을 짓고자 하는 경우
  2. 객체의 멤버 함수에서 객체 자신의 주소를 리턴해야 하는 경우

this의 제약 조건

  1. 클래스의 멤버 함수에서만 사용가능
  2. 멤버 함수라도 정적 멤버 함수(static member funcion)는 this 사용 X

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

c언어에서 사용하는 C-스트링은 할당 받은 메모리 크기 이상의 문자열을 저장할 수 없는 문제가 있다. 하지만 string 클래스는 문자열의 크기에 맞추어 메모리 키기를 조절한다.

string 객체에 문자열 입력

string name
cin >> name // 공백 문자를 입력되면 그 앞까지 문자열을 다룬다.
// but
getline(cin, name, '\n') //'\n'을 만날 때까지 cin으로부터 문자열을 읽어 name에 저장

cin.getline(char* c, sizeof(c),’\n’) <=> geline(cin, string s, ‘\n’)
키보드로 입력한 값을 배열에 저장 : cin.getline() 키보드로 입력한 값을 string 객체에 저장 : getline()

//문자열 비교
if(name < alias) cout<<name<<"이 "<<alias<<"보다 사전에서 먼저 나온다.";
//문자열 연결
string a("I");
a.append(" love");          // a="I love"
//문자열 삽입
string a("i love c++");
a.insert(2, "really");      // a="i really love c++"
a.replace(2, 11, "study")   // idx 2~11(really love)를 "study"로 대체
//문자열 길이
string a("i study c++");
int length = a.lenght();    // length = 11
int size = a.size();        // a = 11
int capacity=a.capacity();  // a의 현재 용량 capacity = 31
//문자열 삭제 
a.clear()
//서브스트링
string b = "i love c++";
string c = b.substr(2,4);   // c = "love"
string d = b.substr(2);     // d = "love c++"
//문자열 검색
a.find("love", 3)           // 찾는문자나문자열을발견하면첫번째인덱스리턴
                            // a의 인덱스 3부터 "love" 문자 검색
//문자열 숫자(str)의 숫자 변환
int n = stoi(a);