#include <iostream>
using namespace std;
// 복사생성자개념
// 1. 복사생성자의모양
// 2. 사용자가만들지않으면컴파일러가만들어준다.( 멤버복사를수행한다. )
// 3. 복사생성자는언제호출되는가?
//             (1) 자신의type으로초기화될때Point p2(p1);
//             (2) 함수호출시call by value - const& 로막을수있다.
//             (3) 함수가객체를값으로리턴할때.!!
//(3)
class Point
{
public:
        Point()                               { cout << "생성자" << endl; }
        Point( int a, int b )  { cout << "생성자" << endl; }
        ~Point()                              { cout << "소멸자" << endl; }
        Point( const Point& p1 ){ cout << "복사생성자" << endl; }
};
Point foo()            //Point p = p1;
{
        //Point p1(1, 2);
        //cout << "foo" << endl;
        //return p1;
        cout << "foo" << endl;
        // 리턴용도로만사용한다면만들면서리턴해라...
        // 리턴용이름없는객체만만들어진다.
        // Return Value Optimization..!!( RVO )
        return Point(1, 2);           // 생성자를사용해서리턴용객체만만든다.
}
void main()
{
        cout << "start" << endl;
        Point p1;
        {
               cout << "in block" << endl;
               foo();
               cout << "out block" << endl;
        }
        cout << "end" << endl;
}
/*
class Point
{
public:
        Point()                               { cout << "생성자" << endl; }
        Point( int a, int b )  { cout << "생성자" << endl; }
        ~Point()                              { cout << "소멸자" << endl; }
        Point( const Point& p1 ){ cout << "복사생성자" << endl; }
};
void foo( Point p )           //Point p = p1;
{
        cout << "foo" << endl;
}
void main()
{
        cout << "start" << endl;
        Point p1;
        {
               cout << "in block" << endl;
               foo( p1 );
               cout << "out block" << endl;
        }
        cout << "end" << endl;
}
*/
/*
class Point
{
public:
        int x;
        int y;
        Point( int a = 0, int b = 0 ) : x(a), y(b) {}
        // 복사생성자: 사용자가만들지않으면컴파일러가만들어준다.
        // 기본적으로멤버복사를수행한다.
        Point( const &Point p )
        {
               x = p.x;
               y = p.y;
        }
};
void main()
{
        Point p1;
        Point p2(1, 2);
        Point p3(p2);          // Point( Point );
        cout << p3.x << endl;
        cout << p3.y << endl;
        Point p4 = p3;         // Point p4(p3);       복사생성자호출
        int a = 0;
        int a(0);
}
*/