복사생성자와 임시객체에 대해서
글쓴이: vani2 / 작성시간: 월, 2013/09/23 - 4:02오후
1. 복사생성자를 다음과 같이 사용하면 단점이 있나요?
Example exp;
Example ex1 = Example(exp);
2. 객체를 함수의 매개변수로 전달할때 값에의한 전달과 참조에의한 전달의 차이가 무엇인가요?
void ab(Person a) {
...
}
void ab(Person& a) {
...
}
여러 소스들을 분석해보면 참조에 의한 전달이 더 효율적으로 보이는데도 불구하고 값에 의한 전달을 사용하는 함수가 많았는데요, 그렇게 하는 이유가 무엇인가요?
3. 복사생성자가 없는 객체를 함수의 인자로 사용할 경우 생성자가 1번 호출되고 파괴자가 2번 호출되던데 이유가 무엇인가요?
4. 임시객체의 소멸시기는 언제인가요?
경우1: 함수의 매개변수로 사용될때
경우2: 수식에 사용될때
경우3: 리턴값으로 사용될때
Forums:
1. ex1 = exp와 비교해서라는 뜻이시죠?
1. ex1 = exp와 비교해서라는 뜻이시죠? ex1 = exp는 복사 생성자를 한번 호출하는 구문이고 적으신 건 복사 생성자를 두번 호출하는 구문입니다.
2. 값은 복사하는 거고 참조는 포인터라고 생각하시면 됩니다. 효율은 객체의 크기가 크지 않다면 별차이가 없습니다. 비상수 참조로 넘기는건 포인터를 넘겼을 때의 문제점과 완전히 동일합니다. 비상수 참조이므로 함수안에서 함수밖에서 온 변수를 조작할 수 있고, 그에 대한 포인터나 참조를 구하는것도 가능합니다. 이게 필요하면 쓰는거고 필요없으면 안쓰는 건데 보통은 상수 참조를 가장 많이 씁니다.
3. 그런일은 없습니다. 정상적으로 종료된 생성자와 파괴자의 호출 횟수는 동일합니다.
4. 함수가 리턴되면(스택에서 내려가면) 소멸됩니다. 모든 구문은 함수입니다. 수식(예를 들어 덧셈 수식은 +연산자의 오버로딩으로 정의됩니다)도 함수입니다. 따라서 따로 구분할 필요가 없습니다. 리턴값의 경우에는 리턴할 때 한번 생성되고 리턴값의 복사 생성자에서 한번 생성된후에 복사 생성자가 리턴되면 함수안에서 생성된 객체가 소멸됩니다. 복사 생성자로 생성된 임시 객체는 함수밖에서 누가 받아주면 그때 또 함수 인자로 넘어가서 처리가 되는거고 아니면 그대로 소멸됩니다.
아하
그렇군요.
3번의 일이 왜 생긴건진 모르겠지만..
잘 이해 되었습니다. 감사합니다 :D
2번에서 차이는 객체가 아니라 기본 자료형으로
2번에서 차이는 객체가 아니라 기본 자료형으로 생각해보면 쉽습니다.
그냥 책에서 레퍼런스 설명하는 그래도 입니다.
레퍼런스면 값을 수정할 수 있습니다.
복사로 넘기면 값이 수정될 일은 없죠.
객체를 레퍼런스로 넘기는건 복사를 안한다는
성능상의 이유 또한 있는데
그럴 경우 값은 수정되면 안될때 const를 붙혀 줍니다.
3번은 짐작컨데 횟수를 생성자와 소멸자에서 출력문으로 확인했으리라 생각되는데
복사 생성자를 안만들면 없는게 아니고
컴파일러가 default로 복사 생성자를 만듭니다.
그래서 출력문을 통한 카운트로는 확인이 안된 것이라 추측되는군요
(복사 생성자는 작동했을겁니다.)
4번에서 임시객체가 리턴되는 경우에는 RVO라고 해서
컴파일러마다 다릅니다.
아...
3번의 경우 말씀하신대로 생성자와 소멸자에 출력문을 넣었는데요,
내부적으로 동적할당을 사용했는데 역시 이게 문제일까요..?
얕은 복사가 이루어진것 같군요.
테스트를 해보셔야 할거 같습니다.
책을 보거나. 네이버에서 검색해보면. 복사생성자에 대해서 알 수 있을거 같습니다.
아래 내용은 정확하지 않으니 대충 참고만 해보세요.
가능한한 직접 테스트를 해보세요.
1. 복사생성자를 다음과 같이 사용하면 단점이 있나요?
- 코드를 해석할때 보기 어렵습니다.
- 코드를 해석해야 알 수 있는 코드는 실무자들에 업무를 괴롭히는 나쁜 코드가 되기 쉽습니다.
2. 객체를 함수의 매개변수로 전달할때 값에의한 전달과 참조에의한 전달의 차이가 무엇인가요?
- 값은 100 바이트를 모두 복사하는거고. (판매)
- 참조는 4 바이트만 넘겨서 사용하는겁니다. (대여)
여러 소스들을 분석해보면 참조에 의한 전달이 더 효율적으로 보이는데도 불구하고 값에 의한 전달을 사용하는 함수가 많았는데요, 그렇게 하는 이유가 무엇인가요?
- 참조를 하게 되면. 어디서 값이 변경되었는지 알 수 없게 되는 경우가 있습니다.
- 값을 사용하게 되면. 값 자체의 보존이 되서 안전합니다. 그렇지만. 속도가 더 느린 문제점이 있습니다.
3. 복사생성자가 없는 객체를 함수의 인자로 사용할 경우 생성자가 1번 호출되고 파괴자가 2번 호출되던데 이유가 무엇인가요?
이 코드를 확인해 보는것이 좋을것 같습니다.
4. 임시객체의 소멸시기는 언제인가요?
경우1: 함수의 매개변수로 사용될때
경우2: 수식에 사용될때
경우3: 리턴값으로 사용될때
코드로 테스트해보시는것이 좋을거 같습니다.
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
친절한 설명 감사드립니다. 그런데
친절한 설명 감사드립니다.
그런데
//error C2556: 'Example *Example::fn_copy(const Example &)' : 오버로드된 함수가 'int Example::fn_copy(const Example &)'과(와) 반환 형식만 다릅니다.
Example* Example::fn_copy(const Example& copy)
{
a = copy.a;
printf("Example복사 함수 : %d %d\n", copy.a, a);
return (Example*)©
}
이 부분이 이해가 잘 되지않네요...
fn_copy 라는 함수가 1개인것 같은데 어떻게 오버로드 된 것인가요?
그건 컴파일 에러가 뜬거 던데요.
ㅇ_ㅇ;; 리턴값이랑 참조가 같으면 그런 경우가 있던거 같습니다.
저도 잘은 모르겠습니다.
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
댓글 달기