C++ - 참조, 복사 생성자, 연산자(operator) 오버로딩
내장형 하드웨어/C++ / 2011. 11. 17. 14:35
- 참조 전달 테스트
→ 따라서 참조를 사용한다.(주소가 같다.)
→ 포인터는 포인터 자체를 저장하는 주소가 또 필요하다.
→ 따라서 참조가 효율적이나 초기화 할 때 들어간 값은 변화하지 않는다.
→ char *const A = &b; 와 같다.
#include<iostream.h>
struct emb
{
int A;
int B;
int C;
int D;
};
// 그냥 arg를 받으면 메모리 사용량이 두배가 된다.
// 따라서 참조를 사용한다.
// 포인터는 포인터 자체를 저장하는 주소가 또 필요하다.
// 따라서 참조가 효율적이나 초기화 할때 들어간 값은 변화하지 않는다.
// char *const A = &b; 와 같다.
void REF(emb &arg)
{
cout << "size : " << sizeof(arg) << endl;
cout << arg.A << endl;
cout << "arg address : " << &arg << endl;
}
int main()
{
emb TEST1 = {0, }; // 멤버 초기화
REF(TEST1);
cout << "TEST1 address : " << &TEST1 << endl;
return 0;
}
→ 함수에서 그냥 arg를 인자로 받으면 메모리 사용량이 두배가 된다.struct emb
{
int A;
int B;
int C;
int D;
};
// 그냥 arg를 받으면 메모리 사용량이 두배가 된다.
// 따라서 참조를 사용한다.
// 포인터는 포인터 자체를 저장하는 주소가 또 필요하다.
// 따라서 참조가 효율적이나 초기화 할때 들어간 값은 변화하지 않는다.
// char *const A = &b; 와 같다.
void REF(emb &arg)
{
cout << "size : " << sizeof(arg) << endl;
cout << arg.A << endl;
cout << "arg address : " << &arg << endl;
}
int main()
{
emb TEST1 = {0, }; // 멤버 초기화
REF(TEST1);
cout << "TEST1 address : " << &TEST1 << endl;
return 0;
}
→ 따라서 참조를 사용한다.(주소가 같다.)
→ 포인터는 포인터 자체를 저장하는 주소가 또 필요하다.
→ 따라서 참조가 효율적이나 초기화 할 때 들어간 값은 변화하지 않는다.
→ char *const A = &b; 와 같다.
- 복사 생성자
→ class를 인자로 받으면 객체를 한번 더 생성한다.
→ 객체는 생성자가 다양하게 있으며 우리가 모르는 생성자가 호출되었다 소멸 되었을 수도 있다.
→ 클래스도 클래스에 대입된다.
→ 대입으로 인한 생성, 초기화 시 생성자가 복사되는데 이때 복사 생성자가 나타난다.
→ 복사생성자는 코딩하지 않아도 자동생성된다.(binary 복사)
※ binary 복사는 위험하다. (메모리 관리에서 문제가 발생할 수도 있다.)
→ 생성자에 malloc을 이용하여 binary 복사를 하고 소멸자에서 free를 했을 때 같은 메모리를 가리키고 있으면 소멸 순서에 따라, 소멸과 함께 먼저 소멸된 메모리를 가리키는 변수들의 세그멘테이션 오류를 발생시킨다.
→ 따라서 복사 생성자를 만들어 준다.
→ 복사 생성자를 만드는 여러 방법이 있으나 참조로 만드는 방법이 효율적이다.
→
→ 위와 같이 함수의 리턴형이 참조인 경우 역시 참조를 리턴하는 함수에 대입이 가능한 것을 확인 할 수 있다.
- 연산자 오버로딩
→ class를 인자로 받으면 객체를 한번 더 생성한다.
→ 객체는 생성자가 다양하게 있으며 우리가 모르는 생성자가 호출되었다 소멸 되었을 수도 있다.
→ 클래스도 클래스에 대입된다.
→ 대입으로 인한 생성, 초기화 시 생성자가 복사되는데 이때 복사 생성자가 나타난다.
→ 복사생성자는 코딩하지 않아도 자동생성된다.(binary 복사)
※ binary 복사는 위험하다. (메모리 관리에서 문제가 발생할 수도 있다.)
→ 생성자에 malloc을 이용하여 binary 복사를 하고 소멸자에서 free를 했을 때 같은 메모리를 가리키고 있으면 소멸 순서에 따라, 소멸과 함께 먼저 소멸된 메모리를 가리키는 변수들의 세그멘테이션 오류를 발생시킨다.
//#include<iostream.h>
#include<stdio.h>
#include<stdlib.h>
class emb
{
public:
int A;
int B;
int C;
int D;
char *E;
emb()
{
A = 50;
B = 50;
C = 50;
D = 50;
E = (char *)malloc(sizeof("TEST"));
strcpy(E, "TEST");
//cout << "생성자 emb()가 생성되었습니다." << endl;
}
emb(emb &KKK)
{
//cout << "복사 생성자가 호출 됨." << endl;
A = KKK.A;
B = KKK.B;
C = KKK.C;
D = KKK.D;
E = (char *)malloc(sizeof(strlen(KKK.E)));
strcpy(E, "TEST");
}
~emb()
{
printf("%08X\n", E);
free(E);
//cout << "소멸자 emb()가 생성되었습니다." << endl;
}
};
// 그냥 arg.A를 쓰면 메모리 사용량이 두배가 된다.
// 따라서 참조를 사용한다.
// 포인터는 포인터 자체를 저장하는 주소가 또 필요하다.
// 따라서 참조가 효율적이나 초기화 할때 들어간 값은 변화하지 않는다.
void REF(emb &arg)
{
//cout << "size : " << sizeof(arg) << endl;
//cout << arg.A << endl;
//cout << "arg address : " << &arg << endl;
}
int main()
{
emb TEST1;
emb TEST2;
emb TEST3 = TEST1; // 복사 생성자(binary 복사)
emb TEST4(TEST1);
TEST4 = TEST1; // 오른쪽에서 왼쪽으로 복사된다.
// 생성될 때 복사 되는게 아니므로
// 복사 생성자를 호출하지 않는다.
//cout << "TEST1 address : " << &TEST1 << endl;
return 0;
}
#include<stdio.h>
#include<stdlib.h>
class emb
{
public:
int A;
int B;
int C;
int D;
char *E;
emb()
{
A = 50;
B = 50;
C = 50;
D = 50;
E = (char *)malloc(sizeof("TEST"));
strcpy(E, "TEST");
//cout << "생성자 emb()가 생성되었습니다." << endl;
}
emb(emb &KKK)
{
//cout << "복사 생성자가 호출 됨." << endl;
A = KKK.A;
B = KKK.B;
C = KKK.C;
D = KKK.D;
E = (char *)malloc(sizeof(strlen(KKK.E)));
strcpy(E, "TEST");
}
~emb()
{
printf("%08X\n", E);
free(E);
//cout << "소멸자 emb()가 생성되었습니다." << endl;
}
};
// 그냥 arg.A를 쓰면 메모리 사용량이 두배가 된다.
// 따라서 참조를 사용한다.
// 포인터는 포인터 자체를 저장하는 주소가 또 필요하다.
// 따라서 참조가 효율적이나 초기화 할때 들어간 값은 변화하지 않는다.
void REF(emb &arg)
{
//cout << "size : " << sizeof(arg) << endl;
//cout << arg.A << endl;
//cout << "arg address : " << &arg << endl;
}
int main()
{
emb TEST1;
emb TEST2;
emb TEST3 = TEST1; // 복사 생성자(binary 복사)
emb TEST4(TEST1);
TEST4 = TEST1; // 오른쪽에서 왼쪽으로 복사된다.
// 생성될 때 복사 되는게 아니므로
// 복사 생성자를 호출하지 않는다.
//cout << "TEST1 address : " << &TEST1 << endl;
return 0;
}
→ 따라서 복사 생성자를 만들어 준다.
→ 복사 생성자를 만드는 여러 방법이 있으나 참조로 만드는 방법이 효율적이다.
→
// 참조
//#include<iostream.h>
#include<stdio.h>
// 함수형 참조
int &TEST()
{
// 지역변수는 고정되지 않으므로 static을 사용해서 고정
static int A = 100;
++A;
return A;
}
int &TEST2()
{
static int A = 50;
return A;
}
int main()
{
int K = TEST(); // K도 참조를 받으므로 K와 A는 같아진다.
// 같은 메모리를 다른 이름으로 가리킨다.
// K의 참조
TEST2();
TEST();
TEST() = 2000; // 좌변은 함수가 호출된 결과이므로 대입된다.
TEST() = TEST2();
printf("TEST() : %d\n", TEST());
printf("K : %d\n", K);
return 0;
}
→ 실행결과//#include<iostream.h>
#include<stdio.h>
// 함수형 참조
int &TEST()
{
// 지역변수는 고정되지 않으므로 static을 사용해서 고정
static int A = 100;
++A;
return A;
}
int &TEST2()
{
static int A = 50;
return A;
}
int main()
{
int K = TEST(); // K도 참조를 받으므로 K와 A는 같아진다.
// 같은 메모리를 다른 이름으로 가리킨다.
// K의 참조
TEST2();
TEST();
TEST() = 2000; // 좌변은 함수가 호출된 결과이므로 대입된다.
TEST() = TEST2();
printf("TEST() : %d\n", TEST());
printf("K : %d\n", K);
return 0;
}
→ 위와 같이 함수의 리턴형이 참조인 경우 역시 참조를 리턴하는 함수에 대입이 가능한 것을 확인 할 수 있다.
- 연산자 오버로딩
'내장형 하드웨어 > C++' 카테고리의 다른 글
C++ - 템플릿(template) (0) | 2011.11.21 |
---|---|
C++ 배열 포인터 복습 (0) | 2011.11.16 |
C++ - 객체 소멸 순서, 객체 생성(정적, 동적 할당-malloc, new) (0) | 2011.11.15 |
C++ - car class 추가, 다중상속, 유도(derivation), 타입 (0) | 2011.11.14 |
C++ 생성자, 소멸자, 상속 (0) | 2011.11.11 |