ㅇ 사용자 정의 요소 --> 심도있게보자
- 클래스 객체를 요소로 가지는 벡터도 만들수 있다.
1 #include <iostream>
2 #include <vector>
3
4 using namespace std;
5
6 class Time
7 {
8 protected:
9 int hour,min,sec;
10 public:
11 Time(int h,int m,int s) { hour=h;min=m;sec=s; }
12 void OutTime() { printf("%d:%d:%d ",hour,min,sec); }
13 };
14
15 template<typename C>
16 void dump(const char *desc, C c)
17 {
18 cout.width(12);cout << left << desc << "==> ";
19 for (unsigned i=0;i<c.size();i++) { c[i].OutTime(); }
20 cout << endl;
21 }
22
23 void main()
24 {
25 vector<Time> vt;
26 vt.push_back(Time(1,1,1));
27 vt.push_back(Time(2,2,2));
28 dump("요소2개",vt);
29 }
- 벡터에 저장된 객체들은 벡터가 파괴될 때 같이 파괴되므로 Time 객체를 별도로 파괴할 필요는 없다.
- 벡터에 직접 객체를 저장하는 것보다는 객체의 포인터를 저장하는 것이 성능상 유리하며 훨씬 더 일반적이다.
- 동적할당 예)
1 #include <iostream>
2 #include <vector>
3
4 using namespace std;
5
6 class Time
7 {
8 protected:
9 int hour,min,sec;
10 public:
11 Time(int h,int m,int s) { hour=h;min=m;sec=s; }
12 void OutTime() { printf("%d:%d:%d ",hour,min,sec); }
13 };
14
15
16 template<typename C>
17 void dump(const char *desc, C c)
18 {
19 cout.width(12);cout << left << desc << "==> ";
20 for (unsigned i=0;i<c.size();i++) { c[i]->OutTime(); }
21 cout << endl;
22 }
23
24 void main()
25 {
26 vector<Time *> vt;
27 vt.push_back(new Time(1,1,1));
28 vt.push_back(new Time(2,2,2));
29 dump("요소2개",vt);
30 vector<Time *>::iterator it;
31 for (it=vt.begin();it!=vt.end();it++) {
32 delete *it;
33 }
34 }
vt 객체는 메모리에 다음과 같이 생성될 것이다.
- 포인터를 가지는 벡터를 파괴할 때는 각 포인터가 가리키는 객체를 직접 파괴해야 한다. --> 그렇지 않으면 메모리 누수 발생
- 임의의 타입에서 일정 조건을 만족하는 타입만 저장할 수 있다.
- 임의 조건을 만족하는 타입 예)
1 #include <iostream>
2 #include <vector>
3 #include <algorithm>
4
5 using namespace std;
6
7 class Dynamic
8 {
9 private:
10 char *ptr;
11 public:
12 Dynamic() {
13 ptr=new char[1];
14 ptr[0]=0;
15 }
16 Dynamic(const char *str) {
17 ptr=new char[strlen(str)+1];
18 strcpy(ptr,str);
19 }
20 Dynamic(const Dynamic &Other) {
21 ptr=new char[strlen(Other.ptr)+1];
22 strcpy(ptr,Other.ptr);
23 }
24 Dynamic &operator =(const Dynamic &Other) {
25 if (this != &Other) {
26 delete [] ptr;
27 ptr=new char[strlen(Other.ptr)+1];
28 strcpy(ptr,Other.ptr);
29 }
30 return *this;
31 }
32 int operator ==(const Dynamic &Other) const {
33 return strcmp(ptr,Other.ptr);
34 }
35 int operator <(const Dynamic &Other) const {
36 return strcmp(ptr,Other.ptr) < 0;
37 }
38 virtual ~Dynamic() {
39 delete [] ptr;
40 }
41 virtual void OutDynamic() {
42 cout << ptr << ' ';
43 }
44 };
45
46 template<typename C>
47 void dump(const char *desc, C c)
48 {
49 cout.width(12);cout << left << desc << "==> ";
50 for (unsigned i=0;i<c.size();i++) { c[i].OutDynamic(); }
51 cout << endl;
52 }
53
54 void main()
55 {
56 vector<Dynamic> vt;
57 Dynamic a("dog");
58 Dynamic b("cow");
59 vt.push_back(a);
60 vt.push_back(b);
61 dump("요소2개",vt);
62 }
- 디폴트 생성자, 변환 생성자, 복사 생성자(깊은복사), =대입연산자, ==, < 비교 연산자, 가상 파괴자 등이 정의 되어 있어야 한다.
- 검색, 정렬 예)
1 #include <iostream>
2 #include <vector>
3 #include <algorithm>
4
5 using namespace std;
6
7 class Dynamic
8 {
9 friend struct DynCompare; 10 friend struct DynFind;
11 private:
12 char *ptr;
13 public:
14 Dynamic() {
15 ptr=new char[1];
16 ptr[0]=0;
17 }
18 Dynamic(const char *str) {
19 ptr=new char[strlen(str)+1];
20 strcpy(ptr,str);
21 }
22 Dynamic(const Dynamic &Other) {
23 ptr=new char[strlen(Other.ptr)+1];
24 strcpy(ptr,Other.ptr);
25 }
26 Dynamic &operator =(const Dynamic &Other) {
27 if (this != &Other) {
28 delete [] ptr;
29 ptr=new char[strlen(Other.ptr)+1];
30 strcpy(ptr,Other.ptr);
31 }
32 return *this;
33 }
34 int operator ==(const Dynamic &Other) const {
35 return strcmp(ptr,Other.ptr);
36 }
37 int operator <(const Dynamic &Other) const {
38 return strcmp(ptr,Other.ptr) < 0;
39 }
40 virtual ~Dynamic() {
41 delete [] ptr;
42 }
43 virtual void OutDynamic() {
44 cout << ptr << ' ';
45 }
46 };
47
48 template<typename C>
49 void dump(const char *desc, C c)
50 {
51 cout.width(12);cout << left << desc << "==> ";
52 for (unsigned i=0;i<c.size();i++) { c[i]->OutDynamic(); }
53 cout << endl;
54 }
55
56 struct DynCompare {
57 bool operator()(Dynamic *a, Dynamic *b) const {
58 return strcmp(a->ptr, b->ptr)<0;
59 }
60 };
61
62 struct DynFind {
63 bool operator()(Dynamic *a) const {
64 return strcmp(a->ptr, "cat")==0;
65 }
66 };
67
68 void main()
69 {
70 vector<Dynamic *> vt;
71 vt.push_back(new Dynamic("dog"));
72 vt.push_back(new Dynamic("cow"));
73 dump("요소2개",vt);
74
75 Dynamic d("cat");
76 puts(find_if(vt.begin(),vt.end(),DynFind())==vt.end() ? "없다":"있다");
77 sort(vt.begin(), vt.end(), DynCompare());
78 dump("정렬후",vt);
79
80 vector<Dynamic *>::iterator it;
81 for (it=vt.begin();it!=vt.end();it++) {
82 delete *it;
83 }
84 }
- 벡터에 포인터를 저장하는 것이 가능하기는 하지만 여러가지 신경써야 할 것들이 많고 불편하기 때문에 벡터에는 통상 값을 저장하는 것이 권장된다.
ps : 출처 및 자세한 내용은 www.WinAPI.co.kr 참고
'[ C/ C++ 프로그래밍 ] > [ STL ]' 카테고리의 다른 글
[ 혼연 정리 ] 시퀀스 컨테이너- 6 [ 리스트 ] (0) | 2010.06.24 |
---|---|
[ 혼연 정리 ] 시퀀스 컨테이너 - 5 [ 벡터 ] (1) | 2010.06.24 |
[ 혼연 정리 ] 시퀀스 컨테이너 - 3 [ 벡터 ] (0) | 2010.06.24 |
[ 혼연 정리 ] 시퀀스 컨테이너 - 2 [ 벡터 ] (0) | 2010.06.24 |
[ 혼연 정리 ] 시퀀스 컨테이너 - 1 [ 벡터 ] (0) | 2010.06.24 |