C++ 객채배열, this포인터, 복사생성자.md!
객체배열
객체 기반의 배열은 다음과 같은 형태로 선언할 수 있다.
1 | SoSimple arrp[10]; |
구조체의 배열 선언과 똑같다. 단 위처럼 객체배열 선언시 생성자에게 매개변수를 전달 할 수 없다.
객체생성시 반드시 무언가를 해야한다면 디폴트 생성자를 추가로 정의해서 사용해야 한다.
포인터를 사용하면 객체배열를 생성하면서 매개변수도 전달 할 수 있다.
1 | SoSimple *ptrArray[10]; |
this포인터
멤버함수 안에서 this라는 이름의 포인터를 볼 수 있다. 간단히 말하면 자기 자신을 가리키는 포인터이다.
1 | ... |
객체 생성후 해당 객체 주소를 this 포인터를 통해 쉽게 획득 가능하다.
주소뿐 아니라 객체의 참좆자 또한 쉽게 구할 수 있다.
1 | ... |
복사생성자
지금까지 아래 방식으로 참조자를 선언, 정의하였다.
1 | int num1 = 20; |
int형 뿐만 아니라 모든 객체가 위와같이 사용 가능하다.
1 | SoSimple sim1(10); |
SoSimple클레스에 SoSimple객체를 매개변수로 받는 생성자가 없어도 자동으로 디폴트 복사생성자가 만들어지기 떄문에 가능하다.
다음이 자동으로 디폴트 복사생성자의 예시이다.
1 | SoSimple(const SoSimple ©) :num(comy.num) |
이렇게 생긴놈이 디폴트 생성자처럼 자동으로 추가된다 생각하면 된다.
보통은 깊은복사(포인터 안의 데이터까지 카피)를 위해 디폴트 복사생성자를 사용하지 않고 별도로 만들어 사용한다.
깊은 복사는 클레스 맴버중에 포인터 변수가 있을경우 보통 사용한다. 디폴트 복사를 통해 객체를 만들면 포인터를 복사해오기 때문에 변수의 위치를 같이 가리킬뿐 그안의 데이터까지 복사해오는것은 아니기 떄문에 데이터까지 복사해오기 위해 사용하는 개념이 깊은 복사다.
복사생성자의 호출 시점
복사생성자가 호출되는 시점은 크게 3가지로 나눌 수 있다.
- 기존에 생성된 객체를 이용해 새로운 객체를 초기화하는 경우
1 | Person man1("Lee dong woo", 29); |
2. call by value 방식의 함수 호출 과정에서 객체를 인자로 전달한 경우
1 | SoSimple SimpleFuncObj(SoSimple ob) |
3. 객체를 반환하되 참조형으로 반환하지 않는 경우.
1 | SoSimple SimpleFuncObj(SoSimple ob) |
다음 코드를 보고 언제 복사생성자가 호출되는지 알아보자. ``` Class SoSimple { private: int num; public: SoSimple(int n) : num(n); {} SoSimple(const SoSimple ©) : num(copy.num) { cout<<"복사생성자 호출"<
{
SoSimple obj(7);
SimpleFuncObj(obj).AddNum(30).ShowData();
//1. ob를 obj로 넘기면서 복사생성자 호출.
//
obj.ShowData();
return 0;
}
//결과는 2번 호출된다.