배열 delete는 익숙해지지 않으면 실수를 계속할 수도 있으니, 배열 반환 시 delete 연산자의 주의사항을 한 번 더 적었다.
int *p = new int [10];
delete p; //비정상 반환. delete[ ] p; 로 하여야함
int *q = new int;
delete [ ] q; //비정상 반환.delete q;로 하여야함
✅new를 이용한 객체의 동적 생성과 생성자
클래스 이름 *포인터 변수 = new 클래스명; // 기본생성자 호출
클래스 이름 *포인터 변수 = new 클래스명(생성자매개변수리스트);
new는 클래스 크기의 메모리를 할당받아 객체를 생성하며, 이때 생성자를 호출한다.
앞의 첫 번째 형식의 경우 기본 생성자가 호출되며, 두 번째의 경우 매개변수를 가진 생성자가 호출된다.
Circle *p = new Circle; //기본 생성자 Circle () 호출. p = new Circle( ); 와 같음
Circle *q = new Circle(30); //생성자 Circle(30) 호출
delete를 이용한 객체 반환과 소멸자
delete 포인터변수;
객체 반환 예시
Circle *p = new Circle; //생성자 Circle()호출. p = new Circle();와 같음
Circle *q = new Circle(30); // 생성자 Circle(30)호출
delete p; // Circle 객체 반환
delete q; // Circle 객체 반환
delete를 사용하면 '포인터변수'는 반드시 new를 통해 동적 할당받은 메모리의 주소여야한다.
Circle donut;
Circle *p = donut;
delete p;//실행 오류, p가 가리키는 객체는 동적 할당받은 것이 아니다
delete실행 시, 객체를 반환하기 직전에 객체의 소멸자가 실행됨
Circle waffle; //(o)
Circle waffle () //(x) 오류를 발생시키지는 않지만 경고를 발생시키기도 한다
waffle.getArea(); //getArea() 왼쪽에 클래스가 있어야 한다 라는 오류 메시지
Circle *p = new Circle();
Circle *q = new Circle();
✅객체와 객체 배열의 동적 생성 및 변환
new를 이용한 객체의 동적 생성과 생성자
클래스명 *포인터 변수 = new 클래스명; //기본생성자 호출
클래스명 *포인터 변수 = new 클래스명(생성자매개변수리스트); //매개 변수 있는 생성자 호출
new는 클래스 크기의 메모리를 할당받아 객체를 생성하며, 이때 생성자를 호출한다.
delete를 이용한 객체 반환과 소멸자
delete 포인터변수;
Circle *p = new Circle; //생성자 Circle() 호출. p = new Circle();와 같음
Circle *q = new Circle(30); //생성자 Circle(30) 호출
delete p; //Circle 객체 반환
delete q; //Circle 객체 반환
delete 사용 시 '포인터변수'는 반드시 new를 이용하여 동적 할당받은 메모리의 주소여야 한다.
Circle donut;
Circle *p = &donut;
delete *p; //실행오류. p가 가리키는 객체는 동적 할당받은 것이 아님
delete가 실행되면, 객체 반환 전에 객체의 소멸자가 실행된다.
매개변수 없는 생성자를 호출 시
Circle waffle; // (O)
Circle waffle(); //(X) 오류를 발생시키지는 않으나 경고는 발생
컴파일러는 위 두 번재 문장을 Circle객체를 리턴하는 함수 waffle()의 선언으로 인지한다.
그러므로 waffle은 함수 이름으로 처리되어 다음과 같이 코딩 시 오류가 발생한다.
waffle.getArea(); // "getArea() 왼쪽에 클래스가 있어야 한다." 라는 오류 메시지
그러나 다음 두 라인은 문제 X
Circle *p = new Circle; //(O);
Circle *q = new Circle(); // (X);
✅객체 배열의 동적 생성 및 반환
new와 delete를 통해 객체 배열을 동적 생성 및 반환
객체 배열의 동적 생성과 생성자
클래스명 *포인터변수 = new 클래스명[배열 크기];
3개의 Circle 객체로 구성된 배열을 동적 생성하는 예시다.
Circle *pArray = new Circle[3]; //3개의 Circle 객체 배열의 동적 생성
new를 이용한 동적 배열을 생성 시, 매개변수가 있는 생성자를 직접 호출할 수는 없다.
대신 다음과 같이 배열을 각 원소 객체로 초기화 가능
Circle *pArray = new Circle[3] { Circle(1), Circle(2), Circle(3) };
// 3개의 객체를 반지름 1, 2, 3으로 각각 초기화한다
객체 배열의 사용
동적으로 생성된 객체 배열은 보통 객체 배열처럼 사용한다
Circle *pArray = new Circle[3];
pArray[0].setRadius(10);
pArray[1].setRadius(20);
pArray[2].setRadius(30;
for(int i=0; i<3; i++){
cout << pArray[i].getArea();}
pArray가 포인터이므로 앞의 코드를 다음과 같이 작성한다.
pArray->setRadius(10);
(pArray+1)->setRadius(20);
(pArray+2)->setRadius(30);
for(int i=0;i<3;i++)
cout << (pArray+i)->getArea();
this 포인터
: 객체 자신에 대한 포인터로서 클래스의 멤버 함수 내에서만 사용된다
this는 전역 변수도 아니고, 함수 내에 선언된 지역 변수도 아니다.
this 는 객체의 멤버 함수가 호출될 때, 컴파일러에 의해 보이지 않게 전달되는 객체에 대한 주소이다.
this와 객체
c1, c2, c3 속에 있는 각 this는 객체 자신에 대한 포인터이다.
각 객체 속의 this는 다른 객체 속의 this와 서로 다른 포인터이다.
this가 필요한 경우
Circle(){
this->radius = 1; //this->를 생략하고 radius = 1;로 해도 무관함
}
🔔this가 꼭 필요한 2가지 경우
1️⃣멤버 변수의 이름과 동일한 이름으로 매개 변수 이름을 짓고자 하는 경우
chicken(int BBurinkle){
this->BBurinkle = BBurinkle;
}
위와 같은 경우에 this를 기입해줘야한다.
2️⃣객체의 멤버 함수에서 객체 자신의 주소를 리턴할 경우
class Sample{
public:
Sample* f(){
~~~~~~~
return this; //현재 객체의 주소 리턴
}
};
연산자 중복을 구현 시, 위와 같은 경우가 많으며 this 없이는 연산자를 중복할 수 없는 경우도 있다.
this의 제약 조건
this가 필요한 경우
1️⃣ this는 클래스의 멤버 함수에서만 사용 가능
멤버가 아닌 함수에서의 this는 어떤 객체에도 속하지 않기 때문
2️⃣멤버 함수라도 정적 멤버 함수(static member function)는 this를 사용할 수 없다.
정젖 멤버 함수는 객체가 생성되기 전에 호출될 수 있고, 정적 멤버 함수가 실행되는 시점에 '현재 객체'는 존재하지 않을 수 있기 때문이다.
'Language & Framework & GIT > C++' 카테고리의 다른 글
[씨앤씨뿔] toupper & tolower함수 : <locale> -1 (0) | 2023.04.27 |
---|---|
[씨앤씨뿔]C++의 getline함수 (4) | 2023.04.27 |
[씨앤씨뿔]C++/ 객체 포인터& 배열& 동적 생성 - 1 (0) | 2023.04.24 |
[씨앤씨뿔]C++/ 클래스 & 객체 - 2 (1) | 2023.04.19 |
[씨앤씨뿔]C++/ 클래스 & 객체 - 1 (0) | 2023.04.18 |
댓글