#include <iostream>
using std::cout;
using std::endl;
using std::ostream;
#include <vector>
using std::vector;
#include <set>
using std::set;
#include <string>
using std::string;
#include <algorithm>
using std::set_intersection;
#include <iterator>
using std::back_inserter;
class Luokkatyyppi {
set<string> tyyppi;
public:
Luokkatyyppi(const string& nimi) {
tyyppi.insert(nimi);
}
void lisaa(const string& nimi) {
tyyppi.insert(nimi);
}
bool on_tyyppia(const Luokkatyyppi &toinen) {
if (this==&toinen) return true;
vector<string> out;
set_intersection(
tyyppi.begin(), tyyppi.end(),
toinen.tyyppi.begin(), toinen.tyyppi.end(),
back_inserter(out));
return !out.empty();
}
friend
ostream& operator << (ostream& out, const Luokkatyyppi &l);
};
ostream& operator << (ostream& out, const Luokkatyyppi &l) {
for (set<string>::const_iterator i=l.tyyppi.begin();
i!=l.tyyppi.end();
++i)
out << *i << ' ';
return out;
}
class Yliluokka {
Luokkatyyppi tyyppi;
public:
static const string TYYPPINIMI;
Yliluokka() : tyyppi(TYYPPINIMI) {
}
void lisaa(const string &nimi) {
tyyppi.lisaa(nimi);
}
bool on_tyyppia(const string& nimi) {
return tyyppi.on_tyyppia(nimi);
}
void tulosta_tyypit() {
cout << "Tyypit: " << tyyppi << endl;
}
void tee(int k) {
cout << "Teenpä jotain " << k << endl;
}
};
const string Yliluokka::TYYPPINIMI="Yliluokka";
class Aliluokka {
Luokkatyyppi tyyppi;
Yliluokka yli;
public:
static const string TYYPPINIMI;
Aliluokka() : tyyppi(TYYPPINIMI) {
tyyppi.lisaa(Yliluokka::TYYPPINIMI);
}
bool on_tyyppia(const string& nimi) {
return tyyppi.on_tyyppia(nimi);
}
void tulosta_tyypit() {
cout << "Tyypit: " << tyyppi << endl;
}
void tee(int k) {
yli.tee(k);
cout << "Teinpä muutakin" << endl;
}
};
const string Aliluokka::TYYPPINIMI="Aliluokka";
int main(void) {
Yliluokka a;
Aliluokka b;
b.tulosta_tyypit();
cout << b.on_tyyppia(Yliluokka::TYYPPINIMI) << endl;
cout << "testataan b.tee(23):" << endl;
b.tee(23);
return 0;
}