#include <string>
#include <iostream>

using namespace std;

class C1 {
protected:
    int i;
public:
    int getI() const { return i; }
    void setI(int i_) { i = i_; }
};

class C2 {
protected:
    string s;
public:
    string getS() const { return s; }
    void setS(string s_) { s = s_; }
};

class C3 {
protected:
    float f;
public:
    float getF() const { return f; }
    void setF(float f_) { f = f_; }
};

class C12 : public virtual C1, public virtual C2
{
};

class C23 : public virtual C2, public virtual C3
{
};

class C123 : public virtual C1, public virtual C12, public virtual C23
{
};


void f1(C1& c1)
{
    cout << "f1:\n";
    cout << "  getI: " << c1.getI() << endl;
}

void f2(C12& c12)
{
    cout << "f2:\n";
    cout << "  getI: " << c12.getI() << endl;
    cout << "  getS: " << c12.getS() << endl;
}

void f3(C23& c23)
{
    cout << "f3:\n";
    cout << "  getS: " << c23.getS() << endl;
    cout << "  getF: " << c23.getF() << endl;
}

void test()
{
    C1 c1;
    c1.setI(1);
    f1(c1);

    cout << "\n===== " << endl;

    C12 c12;
    c12.setI(12);
    c12.setS("str12");
    f1(c12);
    f2(c12);

    cout << "\n===== " << endl;

    C123 c123;
    c123.setI(123);
    c123.setF(1.23f);
    c123.setS("str123");
    f1(c123);
    f2(c123);
    f3(c123);

    cout << "\n===== " << endl;
}

int main()
{
    test();
}
