#include <iostream>
#include <cassert>
using namespace std;

class Fraction
{
private:
    int m_numerator;
    int m_denominator;
public:
    Fraction(int num = 0, int den = 1)
    	: m_numerator(num), m_denominator(den)
    {
        assert(den != 0);
    }
    
    Fraction(const Fraction &fraction) // copy constructor
        : m_numerator(fraction.m_numerator), m_denominator(fraciton.m_denominator)
        {
            cout << "Copy constructor called" << "\n"; //같은 타입의 instance가 들어오면 복사. 
        }
    
    friend std::ostream & operator << (std::ostream & out, const Fraction & f)
    {
        out << f.m_numerator << " / " << f.m_denominator << "\n";
        return out;
    }
};

Fraction doSomething()
{
    Fraction temp(1, 2);
    
    return temp;
}

int main()
{
    Fraction frac(3, 5);
    
    //Fraction fr_copy(frac);
    //or
    //Fraction fr_copy = frac; // 이때도 copy constructor가 호출됨.
    Fraction fr_copy(Fraction(3,10)); // 이 경우엔 copy constructor가 호출 안됨. 컴파일러가 알아서 Fraction을 빼줌.
    
    Fraction result = doSomething(); // debug일땐 호출, release일땐 호출 X => 반환값 최적화.
    
    
    
    cout << frac << " " << fr.copy << "\n";
    
    return 0;
}