2012. 8. 14. 10:37

#include<iostream>

using namespace std;

////////////////////////////////////////////////////////////////////////

//

//복사 생성자 이야기 

//1. 사용자가 복사 생성자를 만들지 않으면 컴파일러가 만들어 준다.

//2. 기본적으로 모든 멤버를 복사 해준다.

//3. C++ 에서 복사생성자가 사용되는 것은 3가지 경우입니다.

// (A) 자신의 타입으로 초기화 될떄 : Point p2(p1)

// (B) 함수인자로 ㄱㄱ체가 값으로 전달될떄 : void foo(Point)

// void foo(const Point &) 를 사용하면 복사생성자 호출을 막을 수 있다.

// Const & 의 장점 : 1. 메모리사용량이 줄어든다.

// 2. 복사 생성자 소멸자의 호출을 막아서 성능 향상된다.

//

// (C)함수가 객체를 값으로 리턴할때 - 임시객체 때문에 복사 생성자가 호출된다. 

// 그럴때 RVO를 사용하면 막을 수 있다.

//

///////////////////////////////////////////////////////////////////////////

/*

class Point{



int x,y;

public:

Point() :x(0),y(0){}

Point(int a, int b) :x(a),y(b){}

//zjavkdlffjsms dkfo ahdiddml todtjdwkfmf wprhdgownsek.

Point(const Point &p):x(p.x),y(p.y){}


};


int main(){


Point p1;

Point p2(1,2);

Point p3(p2); //Point(Point) 모양의 생성자가 필요하다!!


}


*/



/*

class Point{



int x,y;

public:

Point() {cout<<"생성자 1"<<endl;}

Point(int a, int b) {cout<<"생성자 2"<<endl;}

//zjavkdlffjsms dkfo ahdiddml todtjdwkfmf wprhdgownsek.

Point(const Point &p) {cout<<"복사 생성자"<<endl;}

~Point() {cout<<"소멸자"<<endl;}


};

//void foo(Point p){  // 복사생성자와 소멸자가 호출되어 객체가 한번더 호출된다.

void foo(const Point &p)  //const는 그대로 유지되기떄문에 복사생성자가 호출되지 않는다.

{

cout<<"foo"<<endl;

}


int main(){


cout<<"start"<<endl;

Point p1;

cout << "AAA"<<endl;

foo(p1);

cout<<"BBB"<<endl;



}*/



///////////////////////////////////////////////////////////////////////////////////////////////////

///

/// 아래의 코드에 복사 생성자가 들어가있다!! why? return p1 에서 복사생성자에 복사에서 보내기 떄문이다! 

// 1 생성자1 -> AAA -> 생성자2 -> foo -> 복사생성자 -임시객체 -> 소멸자 - 소멸자(임시객체)->BBB-> 소멸자 P

//

////////////////////////////////////////////////////////////////////////////////////////////////////

/*

class Point{



int x,y;

public:

Point() {cout<<"생성자 1"<<endl;}

Point(int a, int b) {cout<<"생성자 2"<<endl;}

//zjavkdlffjsms dkfo ahdiddml todtjdwkfmf wprhdgownsek.

Point(const Point &p) {cout<<"복사 생성자"<<endl;}

~Point() {cout<<"소멸자"<<endl;}


};


Point foo()

{

Point p1(1,2);

cout << "foo" << endl;

return p1;   // 임시 객체를 통해 리턴한다.

}



int main(){


Point p;

cout << "AAA"<<endl;

p=foo();

cout<<"BBB"<<endl;


}

*/

//////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////

//위와같은 문제를 줄여주기 위해 RVO(return value optimization) 이라고 불리는 기술을 사용한다.

///////////////////////////////////////////////////////////////


class Point{



int x,y;

public:

Point() {cout<<"생성자 1"<<endl;}

Point(int a, int b) {cout<<"생성자 2"<<endl;}

//zjavkdlffjsms dkfo ahdiddml todtjdwkfmf wprhdgownsek.

Point(const Point &p) {cout<<"복사 생성자"<<endl;}

~Point() {cout<<"소멸자"<<endl;}


//Point(Point p){} // 이렇게하면 복사생성자가 재귀적으로 무한히 호출되므로 컴파일 에러가 뜬다.

//point(Point &p){} // OK~!

};


Point foo()

{


/////////////////////////////////////////////////////////////////////////////////

// 이름이 있는 객체도 RVO로 자동 리턴된다 NRVO 기술 (Named Return value Optimization)

// VC++ 2005 부터 지원되는 최적화 기술

//

/////////////////////////////////////////////////////////////////////////////////////

// Point p1(1,2);

// cout << "foo" << endl;

// return p1;   // 임시 객체를 통해 리턴한다.  // 리턴하면 성능이 좋치 않다.

//릴리즈 모드를 하면 알아서 RVO 모델로 최적화가 된다. 

cout << "foo"<<endl;

return Point(1,2);

}

int main(){


Point p;

cout << "AAA"<<endl;

p=foo();

cout<<"BBB"<<endl;


}


Posted by k1rha