#include <iostream>
#include <vector>

using namespace std;


class P {
  private:
    string nom;
    
  public:
    P(string n) : nom(n) {
    
    }
    
    virtual string toString() const {
		return "P_" + nom;
	}
};



class I {
  public:
    I(const P &p_, int a) : p(p_), amount(a) {
	}
	
	string desc() const {
	   string s;
	   s += " I_";
	   // call P::toString or PC::toString() ?
	   s += p.toString();
	   
	   return s;
	}
  
  private:
    const P &p;   // could be PC or P
    int amount;
  
};


class R {
	
	private:
	  vector<I> ps;
	  string nom;
	  
	public:
	   R(string n) : nom(n) {
	   }
	   
	   void add(const P & p) {
		   I i(p, 100);
		   ps.push_back(i);
	   }
	   
	   string toString() const {
		   string s;
		   for (auto i : ps) {
			   s += i.desc();
		   }
		   return s;
	   }
	   

};


class PC : public P {
	
	private:
	  R r;
	
	
	public:
	
	PC(string n) : P(n), r(n) {
	}
	
	virtual string toString() const override {
		string s;
		s += "PC ";
		s += P::toString();
		s += r.toString();
		
		return s;
	}
	
	void addToR(const P & p) {
		r.add(p);
	}


};

int main() {

  P p1("abc");
  P p2("def");
  
  PC pc("abc_def");
  pc.addToR(p1);
  pc.addToR(p2);
  
  cout << pc.toString() << endl;
  
  P p3("hij");
  PC pc2("hij_abc_def");
  pc2.addToR(p3);
  pc2.addToR(pc);
  
  cout << pc2.toString() << endl;
  
  return 0;
  
}
