C++ 복사생성사의 호출


#include <iostream>
using namespace std;

class SoSimple
{
private:
    int num;
public:
    SoSimple(int n) : num(n)
    {
        cout << "New Object : " << this << endl;
    }
    SoSimple(const SoSimple& copy) :num(copy.num)
    {
        cout << "New Copy obj: " << this << endl;
    }
    ~SoSimple()
    {
        cout << "Destory obj: " << this << endl;
    }
};

SoSimple SimpleFuncObj(SoSimple ob)
{
    cout << "Parm ADR: " << &ob << endl;
    return ob;
}

int main(void)
{
    SoSimple obj(7);
    SimpleFuncObj(obj);

    cout << endl;

    SoSimple tempRef = SimpleFuncObj(obj);
    cout << "Return Obj " << &tempRef << endl;

    return 0;
}

SoSimple tempRef = SimpleFuncObj(obj);

여기서 tempRef로 SimpleFuncObj(obj)이 복사생성 될줄 알았는데 안그러더라구요.
이리저리 검색해본결과 컴파일러가 효율을 위해 따로 tempRef를 생성하지않는다라고
나와있던데 원래 그런건가요 ?
  • 2016년 05월 17일에 작성됨

조회수 205


1 답변


좋아요
1
싫어요
채택취소하기

어떤 값을 복사 안한다는 의미인지요?

실행결과를 보면 복사생성자가 호출되는 것으로 보입니다. (다음은 g++ 컴파일러를 사용한 경우입니다.)

New Object : 0x7ffffb3509f0      <-- SoSimple obj(7)
New Copy obj: 0x7ffffb350a10     <-- SimpleFuncObj의 obj  인자를 복사하기 위한 복사생성자 호출 );
Parm ADR: 0x7ffffb350a10
New Copy obj: 0x7ffffb350a00     <-- SimpleFuncObj의 return을 위한 복사생성자
Destory obj: 0x7ffffb350a00      <-- SimpleFuncObj 결과를 assign 하지 않음으로 인해 파괴 
Destory obj: 0x7ffffb350a10      <-- SimpleFuncObj의 obj 인자의 파괴

New Copy obj: 0x7ffffb350a20    <-- 두번째 SimpleFuncObj의 obj 인자를 복사하기 위한 복사 생성자 호출
Parm ADR: 0x7ffffb350a20    
New Copy obj: 0x7ffffb3509e0    <-- 두번째 SimpleFuncObj의 return을 위한 복사생성자
Destory obj: 0x7ffffb350a20     <-- 두번째 SimpleFuncObj의 obj 인자의 파괴
Return Obj 0x7ffffb3509e0
Destory obj: 0x7ffffb3509e0     <-- 두번째 SimpleFuncObj의 결과값을 받은 tempRef 파괴
Destory obj: 0x7ffffb3509f0     <-- 최초 obj(7)의 파괴

수정답변 질문의 요지는 다음과 같은것 같네요.

SoSimple copied = original;

위와 같을 때, copied를 생성하기 위해서 복사생성자를 호출합니다.

SoSimple copied = SimpleFuncObj(obj);

그럼 위와 같은 경우에도 "SimpleFuncObj(obj)의 반환된 결과를 copied로 복사하기 위해서 복사생성자를 호출해야 하는 것 아니냐? 그런데 왜 return할 때만 복사생성자를 생성하고, return한 것을 copied에 복사하기 위한 복사생성자를 호출하지 않느냐?" 라는 질문 인것 같네요.

이는 컴파일러의 최적화 문제를 떠나서, 여러가지 복합적인 설명이 가능합니다만, 책에서 읽은 것처럼 설명할 수도 있고, 다른 방식으로 간단히 설명하면,

SimpleFuncObj(...)에서 반환할 때, 복사된 객체는 임시 상태로 존재합니다. 반환하는 순간에는 아직 이 객체를 누가 가리킬지 결정이 되지 않았기 때문입니다. 그런데 이 임시 객체를 copied에 assign하려고 합니다. 말그대로 이 임시 객체는 아무도 참조하지 않고 있어서, 바로 소멸될 예정입니다. 이러한 임시 객체를 굳이 복사할 필요가 있을까요? 앞의 assign(=)에 따르면 소멸할 객체를 복사할 겁니다. 하지만 어차피 참조하는 곳이 없어서 없어질 객체를 복사하는 행위보다는, 임시 객체를 assign(=) 좌측에 있는 이름으로 부르게 하는 게 더 좋지 않을까요? (assign을 통하지 않고, 임시객체가 다른 곳에서 활용될 가능성이 전혀 없기에 가능합니다. 만약 return하는 데, 동시에 여러군데 assign이 가능하다면, 질문자의 생각처럼 복사생성자를 호출하는 것이 맞을 겁니다.)

메커니즘적으로는 실행스택(execution stack)과 관련있습니다. 이에 대한 설명은 운영체제 혹은 컴파일러 이론에서 다루고 있습니다. 실행 스택과 관련된 운용방법과 연관지어 생각해보면 쉽게 이해가 될 것입니다만, 현재로썬 앞의 문단 정도로 이해하시면 됩니다.

  • 2016년 05월 18일에 수정됨
    리눅스(유닉스) 기반의 시스템에서 웹 서비스를 개발하고 있습니다.
  • 2016년 05월 17일에 작성됨
    리눅스(유닉스) 기반의 시스템에서 웹 서비스를 개발하고 있습니다.

  • 질문을 잘못적어서 수정했습니다. ! SoSimple 객체인 tempRef가 생성될줄 알았는데 생성이 안됬다는 뜻이예요.(책에선 객체 하나의 생성을 줄여 효율을 높힌다 라고 적혀있구요)    원종운   2016.5.17 23:03     
  • tempRef 객체가 SimpleFuncObj(obj)에서 리턴된 객체로 복사생성될줄알았어요. 따라서 복사생성자가 Return obj : ~~ 전에 호출될꺼라고 생각했구요. 제가 궁금해 하는걸 재대로 전달하지 못한것같아요 ㅠㅠ 머라고 말해야할지..    원종운   2016.5.17 23:04     
  • 여기를 처음 써봐서 그러는데 여러줄 나눠서 못적나요 ? 엔터를 누르니 덧글이 바로써지네요    원종운   2016.5.17 23:06     
  • 복사생성이라는 말이 참조가 복사되는 것을 말하는 것인자, 복사생성자를 호출하는 것을 애매합니다. 문맥상으로는 생성자를 호출하지 않고 복사하는 것을 원하는 것 같은데, 어떤의미인가요? 복사생성자는 새로운 객체를 만드는 것으로, 레퍼런스 타입을 쓰지 않는 한, 함수인자, return 을 통해서 전달할 때, 항상 복사하기 위해서 복사생성자를 호출합니다.    허대영(Daeyoung Heo)   2016.5.18 00:00     
  • 질문의 요지가 잘 전달되지 않아 죄송합니다 ㅠㅠ 일단 SoSimple tempRef = SimpleFuncObj(obj); 이 코드로 인해 SimpleFuncObj가 호출이 되고 SoSimple형의 객체가 리턴되고 그걸로 tempRef를 초기화하게 됩니다. 여기서 왜 tempRef가 왜 복사생성자를 호출하지 않는지가 궁금합니다. 책에서는 객체를 하나더 만들는것을 줄여 효율을 높인다라고 적혀있는데 컴파일러가 그렇게 최적화를 하는건가요 ? 제 생각대로라면 Return obj: 결과 위에 New Copy obj : tempRef가 SimpleFuncObj(obj)의 리턴값으로 복사생성이 되어야된다고 생각을 합니다.    원종운   2016.5.18 00:13     
  • 수정답변을 달았습니다. 제가 제대로 이해한것이 맞는지 모르겠네요?    허대영(Daeyoung Heo)   2016.5.18 01:13     
  • 완전 감사합니다 ㅠㅠ 이해했어요 책에는 그냥 효율성의 문제로 설명만 해줘서요 맞는말이긴한데 복사생성자의 개념과 직접적으로 연관이 안되서 잘 안받아들여졌거든요    원종운   2016.5.18 01:35     

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close