#include <iostream>
#include <string>
#include <vector>
using namespace std;
// 폴더와File의공통의부모
class Item
{
        string name;
public:
        Item( string s ) : name ( s ) {}
     
        // 상수함수로만들어야상수함수에서불러올수있다.
string GetName() const { return name; }
        virtual int GetSize() = 0;
       // Getname을상수함수로만들자!!
        {
               cout << prefix << GetName() << endl;
        }
};
class File : public Item
{
        int size;
public:
        // 부모클래스에디폴트생성자가없으므로명시적으로부모생성자를호출해줘야한다.
        File( string n, int s ) : Item(n), size(s) {}
        virtual int GetSize() { return size; }
};
class Folder : public Item
{
        vector<Item*> items;
public:
        Folder( string n ) : Item(n) {}
        void Add( Item* p ) { items.push_back(p); }
        virtual int GetSize()
        {
               int sz = 0;
               for ( int i = 0; i < items.size(); ++i )
               {
            // 다형성( Polymorphism ), 가상함수를통해객체에따라다른기능을제공한다.
                       sz += items[i]->GetSize();
               }
               return sz;
        }
        virtual void print( string prefix ) const
        {
               cout << prefix << GetName() << endl;  // 먼저자신의이름출력
               prefix = prefix + string("\t");
               for ( int i = 0; i < items.size(); ++i )
               {
                       items[i]->print( prefix );
               }
        }
};
void main()
{
        Folder* R = new Folder("ROOT");
        Folder* A = new Folder("A");
        Folder* B = new Folder("B");
        R->Add(A);
        R->Add(B);
        R->Add( new File( "a.txt", 10 ) );
        A->Add( new File( "b.txt", 20 ) );
        B->Add( new File( "c.txt", 30 ) );
        cout << R->GetSize() << endl;
        R->print("");
}