Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- C++ class construction test
- C++ 언어에서의 class 생성자에 대하여 몇가지 검증 테스트를 수행해 보았다.
- 나는 항상 다음과 같은 상황을 궁금해 했었다.
- int sum(int a,int b)
- {
- return a + b;
- }
- int s = sum(10,20);
- 위와 같은 상황에서 데이터의 전송이 어떻게 되는지 궁금했었다. 난 오래전에 C/C++ 언어를 배웠다. 88년도에 처음 C 언어를 접했으니 30년이 넘은 이야기이다.
- 그때부터 쭉.. 다음과 같이 생각했었다.
- sum 이라는 함수에 10과 20이라는 상수 값이 sum 함수의 인수 a와 b에 전달된다.
- a 와 b는 sum 함수의 인수이다. 인수 역시 local 변수라는 것은 자명하다.
- 메모리로 보면 처음의 10, 20 은 상수로 메모리에 존재한다.
- a 와 b 는 변수로 메모리에 존재하며 이는 sum 이 호출될 때 준비된다.
- return a+b 에 의하여 a 와 b를 더한 값을 sum 함수의 결과 변수(메모리 위치???) 에 저장하게 된다 , 이 메모리를 *sum 이라 해보자.
- s = sum(10,20) 은 결국 s = *sum ; 이 될 것이다.
- 위의 과정에서 상수 2개, 인수 2개, a+b 결과 1개, s 1개 ,,, 총 2+2+1+1 = 6개의 저장 공간이 필요하다.
- 연산자는 대입연산자와 + 더하기 연산자가 사용된다.
- 대입 연산자를 찾아볼까????
- sum(10,20) 에 의하여 10과 20이 각각 int a, int b 인수에 전달될때 2번의 대입연산자가 발생한다. 또한 sum 함수 에서 a+b 의 결과를 *sum 에 전달하기 위하여 필요하다.
- 또한 return 된 값을 s 에 대입하기 위하여 대입 연산자가 필요하다.
- 총 4번이 필요하다.
- 이 과정에서 나는 항상 다음에 대한 궁금증을 가지고 있었다.
- a+b 결과를 *sum 에 넣고 이를 다시 s 에 전달해야 하는가???
- 이러한 overhead 를 제거하기 위해서 call by reference를 사용하는 경우가 있기도 하지만, 알다 시피 c/c++ 에서 call by reference 를 사용할 경우 정상적인 수학적 공식에서 멀어진다는 것이다.
- 가령
- y = sum(10,20)+sum(30+40) ;
- 이런식을 표현 못한다는 것이다.
- 그래서 다음과 같은 형식을 컴파일 해보았다.
- int &s = sum(10,20);
- 좀 이상하다…. ㅎㅎ 결국 컴파일은 오류가 난다. 당연하지….
- 그러면????
- const int &s = sum(10,20);
- const 로 받는다??? ….. 컴파일이 된다.. 결과도 나온다...
- 결과를 read only로만 사용할 거면 이렇게 하면 된다.
- 이러다 문득 class 를 return 하게 되면 어떨까???? class는 생성자를 사용하여 메모리 생성 갯수를 세어 볼수 있으니까…
- 여러가지를 테스트해보기 위하여 다음과 같은 class C 를 준비 하였다.
- cprintf() 함수는 직접 만들어 사용하는 원격 debug 창으로 format 문자열을 전송하는 함수라는 것을 참고하기 바란다. c언어의 printf 라고 생각하면 될듯하다.
- int idx = 0;
- class C
- {
- public:
- int v;
- C() : v(0)
- {
- cprintf("C() idx=%d",++idx);
- }
- C(int _v) : v(_v)
- {
- cprintf("C(int_v) v=%d,idx=%d",v,++idx);
- }
- C(const C &c) : v(c.v)
- {
- cprintf("C(conts C &c) idx=%d",++idx);
- }
- C & operator = (const C &c)
- {
- cprintf("operator = (conts C &c) idx=%d",++idx);
- v = c.v;
- return *this;
- }
- };
- C sum(const C &a,const C &b)
- {
- return C(a.v+b.v);
- }
- 생성자가 3가지 이고 operator overloading = 이 하나 있다.
- operator overloading 은 자기복제 생성자와 연관성을 보기 위해서 준비한 것이다.
- c++ 언어의 기초… 쉬운것부터 가보자.
- C a;
- 하면 ? ,
- 당연히
- C() idx=1
- sum 함수의 인수 전달에는 call by reference의 형식이라는 것을 감안하기 바란다.
- 이제 본격적으로
- C ret = sum(C(10),C(20));
- 어떻게 호출될까???
- 의외의 결과가 나왔다. 물론
- 출력결과
- C(int_v) v=10,idx=1
- C(int_v) v=20,idx=2
- C(int_v) v=30,idx=3
- 위이 결과로 다음을 추론할 수 있다.
- 인수에 들어가는 class의 생성자는 앞의 것부터 호출 된다. 즉 C(10)->C(20) 순서로.
- 특이한 것은 C ret 로 오는데 생성자가 한번 호출된 것이다. 예상으로는 두번 호출될줄 알았는데… 최적화가 되는건가???
- 아니면 operator overloading 이 호출된건가??? 그렇지 않다.. operator overloading 도 분명 호출 되었으면 메시지가 나온다. 동작 상태를 보기 위해
- C ret = sum(C(10),C(20));
- C ret2 = ret;
- 출력결과.
- C(int_v) v=10,idx=1
- C(int_v) v=20,idx=2
- C(int_v) v=30,idx=3
- C(conts C &c) idx=4
- C ret2 = ret; 는 자기 복제 연산자 호출이구나...
- 그러면…
- C ret = sum(C(10),C(20));
- C ret2;
- ret2 = ret;
- 출력결과.
- C(int_v) v=10,idx=1
- C(int_v) v=20,idx=2
- C(int_v) v=30,idx=3
- C() idx=4
- operator = (conts C &c) idx=5
- 그렇지….. 당연한 결과.. 그러나 아무튼 C ret=sum(C(10),C(20)) 에서 앞에서 말한 *sum 에 해당하는 부분이 없다는 것이다. 최적화 되는듯 하다.
- 그러면 다음과 같이 해보자.
- const C &ret = sum(C(10),C(20));
- C ret2;
- ret2 = ret;
- C(int_v) v=10,idx=1
- C(int_v) v=20,idx=2
- C(int_v) v=30,idx=3
- C() idx=4
- operator = (conts C &c) idx=5
- 결과적을 똑같다. 즉 C ret; 메모리를 sum 의 결과 계산에 직접 사용한다는 것이거나 ret 메모리 주소를 sum의 결과로 잡아 준다는 것이거나…
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement