ネタ元 → 勝手にじゃんけん祭り 
振られたネタは買いましょう♪
力技で勝ち負け判定してます。
#include <iostream>
#include <string>
using namespace std;
enum result { even, win, lose, none=-1 };
string to_string(result r) {
  switch ( r ) {
  case even : return "even";
  case win  : return "win ";
  case lose : return "lose";
  }
  return none;
}
class hand {
public:
  virtual ~hand() {}
  virtual result judge(const hand&) const = 0;
  virtual string name() const =0;
};
class G : public hand {
public:
  virtual result judge(const hand& your_hand) const;
  virtual string name() const { return "G"; }
};
class C : public hand {
public:
  virtual result judge(const hand& your_hand) const;
  virtual string name() const { return "C"; }
};
class P : public hand {
public:
  virtual result judge(const hand& your_hand) const;
  virtual string name() const { return "P"; }
};
result G::judge(const hand& your_hand) const {
  if ( dynamic_cast<const G*>(&your_hand) ) return even;
  if ( dynamic_cast<const C*>(&your_hand) ) return win;
  if ( dynamic_cast<const P*>(&your_hand) ) return lose;
  return none;
}
result C::judge(const hand& your_hand) const {
  if ( dynamic_cast<const G*>(&your_hand) ) return lose;
  if ( dynamic_cast<const C*>(&your_hand) ) return even;
  if ( dynamic_cast<const P*>(&your_hand) ) return win;
  return none;
}
result P::judge(const hand& your_hand) const {
  if ( dynamic_cast<const G*>(&your_hand) ) return win;
  if ( dynamic_cast<const C*>(&your_hand) ) return lose;
  if ( dynamic_cast<const P*>(&your_hand) ) return even;
  return none;
}
int main() {
  hand* h[3];
  G g;
  C c;
  P p;
  h[0] = &g; h[1] = &c; h[2] = &p;
  for ( int i = 0; i < 3; ++i ) {
    for ( int j = 0; j < 3; ++j ) {
      cout << h[i]->name() << ':' << to_string(h[i]->judge(*h[j])) << " - "
           << h[j]->name() << ':' << to_string(h[j]->judge(*h[i])) << endl;
    }
  }
}