[질문] C++ 복사생성자(copy constructor)
글쓴이: hermian / 작성시간: 수, 2006/08/23 - 10:24오전
#include <iostream> using std::endl; using std::cout; class Point{ public: Point(int _x=0, int _y=0):x(_x), y(_y){ cout << "Called Ctor" << endl; } Point(const Point &p) : x(p.x), y(p.y) { cout << "Called Copy ctor" << endl; } const Point& operator=(const Point& p) { cout << "Called operator= member function" <<endl; if (&p == this) return *this; x = p.x; y = p.y; return *this; } void ShowPosition() { cout << x << " " << y << endl; } Point operator+(const Point& p) const; private: int x; int y; }; Point Point::operator+(const Point& p) const { cout << "1. operator+" << endl; Point temp(x+p.x, y+p.y); cout << "2. operator+" << endl; return temp; // called copy ctor } int main(void) { Point p1(1, 2); Point p2(2, 1); Point p3=p1+p2; return 0; }
/// result
Called Ctor
Called Ctor
1. operator+
Called Ctor
2. operator+
g++ --version
g++ (GCC) 3.3.1
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Point p3=p1+p2;
의 경우 Ctor도 Copy Ctor도 operator=도 불리우지 않습니다.
operator+에서 Copy Ctor이 불리어야 하지 않는지요?
조언 부탁드립니다.
8월 25일 답변이 없어 오늘 봤더니 소스가 잘렸더군요.
Forums:
오늘 새로운 시험을
오늘 새로운 시험을 해봤습니다.
아래 소스의 main에서 p3의 생성자 호출이 없습니다.
대충 이해는 가지만, 정확히는 모르겠군요.
명확한 설명 좀 부탁드립니다.
결과
Called Ctor : 1,2 : 0xfeffd140 <-- p1 생성자
Called Ctor : 2,1 : 0xfeffd130 <-- p2 생성자
Called operator+ : 0xfeffd140 <-- p1.operator+
Called Ctor : 3,3 : 0xfeffd120 <-- temp 생성자
end operator+
0xfeffd120 : 3 3 <-- temp.ShowPosition()
Called Xtor : 0xfeffd120 <-- temp 소멸자
Called Xtor : 0xfeffd130 <-- p2 소멸자
Called Xtor : 0xfeffd140 <-- p1 소멸자
Point p3=p1+p2;위
위 문장은 definition이므로 '='는 initializer이지 assignment operator가 아닙니다.
ctor이 호출됩니다.
풀어 쓰면
원래는
이겠으나
만약 컴파일러가 이렇게 한다면
컴파일러 지적 수준이 땡칠이므로 버리고 딴 거 쓰세요.
컴파일러가 쓸데 없는 copy ctor 호출을 피하는 겁니다.
id 만들 때 앞에 underscore '_'는 피하는 게 좋습니다.
(_XXX : C reserved, __XXX C++ reserved)
이름이 충돌하면 namespace 씌우면 되겠지만
MACRO에겐 소용 없지요.
그리고 destructor는 약자로 dtor입니다.
___________________________________
Less is More (Robert Browning)
___________________________________
Less is More (Robert Browning)
C++ 컴파일러에 따라
C++ 컴파일러에 따라 약간씩 달라질 수 있습니다.
원칙대로라면 temp를 만들고, 그 값이 copy constructor를 써서 temp에서 복사해야 하겠지만, 이 과정을 계속 하다보면 너무나도 느려질 가능성이 있습니다.
따라서 C++ 표준에는 임시 object A에서 copy constructor를 써서 object B를 만들 경우, 처음에 임시 object를 만들때 아예 B에서 만드는 것을 허락합니다. 따라서 p3의 경우, copy constructor가 쓰이지 않은 것입니다. 그리고 temp를 만드는 constructor 자체가 p3의 constructor에 해당합니다. (ISO C++ Standard 12.8.15)
--
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://www.cinsk.org/cfaqs/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
부연하면 이를 return
부연하면 이를 return value optimization(RVO)라고 부릅니다.
gcc는 RVO에 의해 2개의 임시 개체의 생성을 회피했습니다.
operator+() 내의 temp와 이를 반환하면서 복사생성자에 의해 생기는 개체.
꽤 똑똑한 컴파일러죠.
이름이 붙은 임시 개체(temp 같은 것)에는 RVO를 적용하지 않는 컴파일러도 있습니다.
이런 경우
이렇게 하기보다는
로 하면 RVO를 수행할 가능성이 더 높습니다.
댓글 달기