04 Chapter - 객체 포인터와 객체 배열, 객체의 동적 생성
1. 객체 포인터
- 객체에 대한 포인터 변수 선언
Circle *p;
- 포인터 변수에 객체 주소 지정
p = &donut; // p에 donut 객체 주소 저장
Circle* p = &donut; // 선언과 동시에 초기화
- 포인터를 이용한 객체 멤버 접근
d = donut.getArea(); //객체 이름으로 멤버 함수 호출
d = p->getArea(); //포인터로 객체 멤버 함수 호출
d = (*p).getArea();
※ 초기화 하지 않은 객체 포인터를 이용하면 오류(null pointer assignment)가 발생한다
2. 객체 배열
1) 객체 배열 선언 및 활용
- 객체 배열 선언
Circle circleArray[3];
- circleArray는 3개의 Circle 객체를 원소로 가지는 배열이다.
- 객체 배열 선언문은 각 객체마다의 기본생성자를 호출함
- 기본생성자를 선언하지 않고 매개변수를 가진 생성자를 선언했으면 객체배열 선언시 오류발생함
▶ 따라서 객체 배열 선언 시, 기본 생성자가 있는지 꼭 확인!
- 객체 배열 사용
circleArray[0].setRadius(10);
circleArray[1].setRadius(20);
circleArray[2].setRadius(30);
- Circle 클래스의 포인터를 이용해 배열을 다룰 수 있음
Circle *p;
p = circleArray; //p는 circleArray 배열을 가르킨다.
for(int i=0; i<3; i++) {
cout << p->getArea() << endl;
p++; //다음Circle 객체 주소로 증가
}
- 배열 소멸과 소멸자
- 함수가 종료하면 함수 내 선언된 배열도 소멸된다.
- 배열이 소멸되면, 모든 원소 객체가 소멸되며 각 원소 객체마다 소멸자가 호출된다.
- 가장 높은 인덱스에서부터 원소 객체가 소멸되고, 각 객체마다 ~Circle() 소멸자가 실행된다.
- 객체 배열 초기화
Circle circleArray[3] = { Circle(10), Circle(20), Circle() };
- 배열을 선언 할때 { } 안에 호출할 생성자를 지정한다.
2) 다차원 객체 배열
- c++에서는 다차원 객체 배열을 만들 수 있다.
Circle circles[2][3]; //2행 3열의 2차원 객체 배열 생성
- 2차원 배열도 1차원 배열과 동일하게, 각 원소 객체가 생성될 때, 기본 생성자 Circle이 실행된다.
- 2차원 객체 배열 초기화 방법
circles[x][y].setRadious(i); //x행 y열의 객체의 radius값을 1로 초기화
Circle circles[2][3] = { { Circle(1), Circle(2), Circle(3) }, { ... } }
3. 동적 메모리 할당 및 반환
- 실행 중에 필요한 만큼 메모리를 할당받고 필요없을 때 반환하게 할 수있는 방법
- C++에서는 new와 delete 연산자를 사용해서 할당/반환한다.
1) new와 delete 연산자
- new와 delete의 기본 활용
데이터타입 *포인터변수 = new 데이터타입;
delete 포인터변수;
- new 연산자는 '데이터타입'의 크기만큼 힙으로부터 메모릴 할당받고 주소를 리턴한다.
- '포인터변수'는 할당받은 메모리의 주소를 가지게 된다.
- delete연산자는 '포인터변수'가 가르키는 메모리를 힙을 반환한다.
ex) new와 delete를 활용한 예제
int *p = new int;
if(!p) return; //메모리 할당받기 실패
*p = 5;
int n = *p; //n=5
delete p;
- 동적 할당 메모리 초기화
int *pInt = new int(2); //2로 초기화된 int 공간 할당
- delete 사용시 주의
- delete로 메모리를 반환할 때 적절하지 못한 포인터를 사용하면 실행 오류가 발생한다.
int n;
int *p = &n;
delete p; //실행 오류, p가 동적할당 받은게 아님
2) 배열의 동적 할당 및 반환
- 배열의 동적 할당/반환의 기본 형식
데이터타입 *포인터변수 = new 데이터타입 [배열의 크기];
delete [] 포인터변수;
- 보통 배열과 동일한 방식으로 활용이 가능하다.
- 배열 초기화시 주의 사항
- new로 배열을 동적 할당받을 때 다음과 같이 생성자를 통해 직접 '초깃값'을 지정할 수없다.
int *pArray = new int [10][20]; // 구문 오류. 배열의 초기화는 불가
int *pArray = new int [] {1, 2, 3, 4} //이런 방식으로는 초기화 가능
4. 객체와 객체 배열의 동적 생성 및 반환
1) 객체의 동적 생성 및 반환
- new를 이용한 객체의 동적 생성과 생성자
클래스이름 *포인터변수 = new 클래스이름; //기본 생성자 호출
클래스이름 *포인터변수 = new 클래스이름(생성자매개변수리스트); //매개변수 있는 생성자 호출
- delete를 이용한 객체 반환과 소멸자
delete 포인터변수;
delete 사용 시 '포인터 변수는' 반드시 new로 동적할당 받은 메모리의 주소여야 한다.
2) 객체 배열의 동적 생성 및 반환
- 객체 배열의 동적 생성과 생성자
클래스이름 *포인터변수 = new 클래스이름 [배열 크기];
Circle *pArray = new Circle[3];
* 매개변수 있는 생성자를 직접 호출할 수는 없다.
Circle *pArray = new Circle[3]{ Circle(1), Circle(2), Circle(3) };
위와 같이 초기화는 가능하다.
- 객체 배열의 사용
pArray[0].setRadius(10);
// 배열의 첫번째 객체의 setRadius()멤버 함수 호출
pArray->setRadius(10);
(pArray+1)->setRadius(20); //이렇게도 가능하다.
- 배열의 반환과 소멸자
delete [] 포인터변수;
*소멸자의 실행 순서는 생성의 반대순이다.
5. this 포인터
- this는 객체 자신에 대한 포인터로서 클래스 멤버 함수 내에서만 사용된다.
- this는 변수가 아니고, 객체에 대한 주소이다.
1) this와 객체
- this는 객체 자신에 대한 포인터 이다.
2) this가 필요한 경우
- 다음과 같은 생성자 함수의 경우 'this->' 생략이 가능하다.
Circle() {
this->radius = 1;
}
ⓐ 멤버 변수 이름과 동일한 이름으로 매개변수 이름을 짓는 경우
ⓑ 객체의 멤버 함수에서 객체 자신의 주소를 리턴할 경우
3) this의 제약 조건
- this는 클래스의 멤버함수에서만 사용할 수 있다.
- 멤버함수라도 정적 멤버 함수는 this를 사용할 수 없다.
6. string 클래스를 이용한 문자열 사용
1) string 객체 생성 및 출력
- string 객체 생성
string str1;
string str2("안녕하세요");
string str3(str2); //str2를 복사한 str3생성
- string 객체의 동적 생성
string *p = new string("C++");
cout << *p;
p->append(" Great!");
cout << "*p";
delete p;
- string 멤버 함수/연산자
string - C++ Reference (cplusplus.com)
* 모를 땐 레퍼런스를 보자!!
2) 문자열 다루기
- 문자열 치환
string a = "java", b= "c++";
a = b; //a가 "c++"이 된다.
- 문자열 비교
string a = "java", b= "c++";
int res = a.compare(b); //a와 b를 비교한다.
//같으면 0, 양수면 사전순으로 a가 앞, 반대는 b가 앞
- 문자열 연결
string a = "java", b= "c++";
a.append("hate"); // a = "javahate"
a+=b; // b = "javac++"
- 문자열 삽입
string s("I love c++");
a.insert(2, "really ");
a.replace(2, 11, "study"); //2~11의 인덱스의 문자를 치환
- 문자열 길이 : length(), size(), capcity(문자열의 현재 용량?)
- 문자열 삭제
stirng s("hello");
s.erase(0,2);
a.clear(); // s=""
- 서브스트링
string b = "I love c++";
string c = b.substr(2,4);
string d = b.substr(2); //인덱스 2부터 끝까지 문자열 리턴
- 문자열 검색
int idx = s.find("love"); //love가 있는 첫번째 인덱스 반환, 없으면 -1
- 문자열의 숫자 변환
string year = "2021"l
int n = stoi(year); //int형으로 변환된다.
- 문자 다루기 : <locale>헤더파일안에 있음 ex) toupper(), isdigit(), isalpha()
내용 개많다...
'Major > C&C++' 카테고리의 다른 글
[C++] 문자열 자르기, 자른 문자열 배열에 담기(strtok이용) (0) | 2021.08.26 |
---|---|
[C++] 명품 C++ Programming 4장 연습문제 (4) | 2021.08.25 |
[C++] 명품 C++ Programming 3장 연습문제 (0) | 2021.08.07 |
[C++] 명품 C++ Programming 3장 개념정리 (2) (0) | 2021.07.28 |
[C++] 명품 C++ Programming 3장 개념정리 (1) (0) | 2021.07.24 |