[ how to store objects or object pointers in vectors ]
C++ 초심자의 경우, vector에 객체 혹은 객체에 대한 포인터를 담을 때 어떠한 원리로 담기는 지는 잘 와닿지 않습니다.
저도 vector<pointer형> vectorName(길이, new 자료형());
식으로 vector을 선언할 떄 생성자가 한 번만 호출되는 것이 의아하고 이해가 안되었었기에 글로 다시 한 번 남깁니다.
기본적인 vector 의 생성 예시는 다음과 같습니다.
vector<자료형> 변수명(자료 개수)
vector<자료형> 변수명(자료 개수, 초깃값)
Point라는 클래스가 있고 이 클래스는 생성자 2가지가 존재한다고 합시다.
1. Point()
2. Point(int x, y)
그 경우 vector를 생성할 수 있는 예시는 다음과 같습니다.
vector<Point> v1(5);
//5개의 Point 객체를 담는 vector v1 생성, 이 때 default 생성자로 5개 생성됨.
vector<Point> v2(5, Point(10,10));
//Point(10,10)을 생성하고 이 익명 객체를 바탕으로 5번의 복사 생성자를 호출하여 vector의 각 칸을 초기화함.
vector<Point*> v3(5);
//NULL pointer 5개로 vector의 각 칸을 초기화함.
vector<Point* v4(5, new Point(20,20);
//Point(20,20)을 이용해 동적으로 Point객체를 생성하고 그 객체에 대한 주소값을 이용해 Point pointer를 초기화함.
위에서 첫 번째와 두 번째는 맨 위에서 얘기한 기본적인 사용법과 일치하고,
세 번째 네 번째가 조금 어렵다.
세 번째의 경우 pointer는 default 값이 NULL 이라 그렇게 되는 것이고,
네 번째의 경우에는 다소 혼란스러울 수 있는데, 결과적으로 객체는 하나가 생성되고, 따라서 생성자든 복사생성자든 상관없이, 생성자만 한 번 생성되고, vector의 각 칸(pointer임. )그 생성된 객체의 주소를 저장할 뿐이다.
vector<Point> v2(5, Point(10,10));
즉 위의 코드에서는 각 vector의 칸들에게 넣을 객체의 원본을 생성자로 생성하고,
vector의 각 칸은 방금 생성한 익명 객체 (anonymous object)를 이용하여 복사생성자로 생성된다.
따라서 생성자 1번, 복사생성자 5번이 호출된다.
vector<Point* v4(5, new Point(20,20);
하지만 위의 코드에서는 new Point(20,20)에 의해 객체가 생성자를 이용해 하나 동적으로 생성되고,
vecotr의 각 칸은 방금 생성한 익명 객체 (anonymous object)의 주소값을 저장하는 pointer 변수가 저장된다.
따라서 vector의 각 칸은 그저 주소값을 저장하는 pointer일 뿐이므로, 생성자는 단 한 번만 호출된다.
전체 소스 코드가 아래와 같다고 합시다.
#include
#include
using namespace std;
class Point
{
public:
int x, y;
public:
Point(int x = 0, int y = 0)
{
cout << "( "< x = x;
this->y = y;
}
Point(const Point& p)
{
this->x = p.x;
this->y = p.y;
cout << "복사생성자!" << endl;
}
};
int main()
{
//하나를 생성하고 걔를 이용해 각 칸마다 복사 생성자
vector v2(5, Point(10,10));
cout << "===================" << endl;
vector v4(5, new Point(20, 20));
//얘는 왜 생성자 하나만 호출 돼?
//-> 그 객체에 대한 주소값을 각 포인터 변수들이 받는 것일 뿐!!
cout << "===================" << endl << endl;
cout <<"!헷갈림 주의!" << endl;
cout << "Point의 pointer형을 저장하는 vector v4의 0번 인덱스에 위치한 pointer가 참조하는 Point 객체의 주소값" << endl;
cout << &(*v4[0]) << endl;
cout << "Point의 poiner형을 저장하는 vector v4의 1번 인덱스에 위치한 pointer가 참조하는 Point 객체의 주소값" << endl;
cout << &(*v4[1]) << endl;
cout << "즉 모두 같은 Point 객체를 참조한다." << endl;
}
Output
설명한 바와 같이
vector v2(5, Point(10,10));
는 한 번의 생성자와 5번의 복사생성자가 호출되었고,
vector v4(5, new Point(20, 20));
는 한 번만 생성자가 호출되고, 주소값 출력결과를 보아 벡터 내의 각 칸의 pointer들은 모두 방금 생성된 같은 객체의 주소를 저장한다는 것을 알 수 있다.
'C++' 카테고리의 다른 글
[백준알고리즘] 1931번 회의실 배정 (0) | 2019.07.28 |
---|---|
C++의 객체 배열, 오브젝트 배열 사용법과 원리 (0) | 2019.05.15 |
[C++ 예제] C++ 텍스트 파일 파싱하기 (0) | 2018.04.08 |
[C++] 실습 텍스트 파일 파싱하기 (0) | 2018.03.28 |