#include <iostream>
#include <vector>
#include <functional>

using namespace std;

class Base
{
public:
    int m_i = 0;
    
    virtual void print()
    {
        cout << "I'm Base" << "\n";
    }
};

class Derived : public Base
{
public:
    int m_j = 1;
    
    virtual void print() override
    {
        cout << "I'm derived" << "\n";
    }
};

void doSomething(Base & b)
{
    b.print(); // &b에 d를 넣어도 다형성처럼 구현이 된다. I'm dervied 출력. 이것도 &가 없다면 마찬가지로 I'm Base 출력
}

int main()
{	
    Derived d;
    Base &b = d;
    
    b.print(); // I'm derived 출력. 
    
    // 만약 Base b = d; 라고 선언했다면,
    // m_j 에 대한 정보는 받아들이지 못하고 사라져버린다.
    // 그리고 b.print()를 실행해보면 I'm Base라고 나오면서 다형성이 사라져버린다.
    
    // 이런 경우 객체 잘림 발생
    //std::vector<Base> my_vec;
    //my_vec.push_back(b);
    //my_vec.push_back(d);
    
    //for (auto & ele : my_vec)
    //    ele.print(); // I'm base만 두번 나온다. push_back을 하는 과정에서 슬라이싱 발생
    
    // vector<Base&> 과 같이는 쓸 수 없다. vector는 &은 지원하지 않기 때문
    // 꼭 &을 쓰고싶다하면 functional을 이용하도록 한다.
    std::vector<std::reference_wrapper<Base>> my_vec;
    my_vec.push_back(b);
    my_vec.push_back(d);
    
    for (auto & ele : my_vec)
        ele.get().print(); // get()은 레퍼런스를 가져오는 함수
    
    return 0;
}