C ++ - interfaces, inheritance, polymorphism

Imagine this scenario:

  • interface I1 : m1()implemented by class C1
  • interface I2 : m2()implemented by class C2
  • I3 interface : m3()implemented by class C3

And I want to define functions that take an argument arg.

void f1(I1 arg) {
    use m1()
}

void f2([I1, I2] arg) {
    use m1() and m2()
}

void f3([I2, I3] arg) {
    use m2() and m3()
}

Then I want to determine:

  • interface "union" I123 , which has all the methods implemented by C123
  • class "union" C123 , which inherits implemented methods from existing classes C1 , C2 , C3 .

C123 f1, f2, f3.

C123 obj;

f1(obj);
f2(obj);
f3(obj);

  • ++?
  • ? . f2 [C1, C2] [I1, I2].

#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 C23 : public C2, public C3 {};
class C123 : public C1, public C2, public C3 {};

void f3(C23 arg) {
  arg.setS(to_string(arg.getF()));
}


int main() {

  C123 obj;

  f3(obj);

  std::cout << obj.getS();
}

a.cc: In functionint main()’:
a.cc:42:9: error: could not convertobjfromC123toC23f3(obj);
+4
3
  • ++?

, ++.

#include <string>
#include <iostream>

using namespace std;

class I1 {
public:
    virtual int getI() const = 0;
    virtual void setI(int i) = 0;
};

class I2 {
public:
    virtual string getS() const = 0;
    virtual void setS(string s) = 0;
};

class I3 {
public:
    virtual float getF() const = 0;
    virtual void setF(float f) = 0;
};

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

class C12 : public I1, public I2 {
protected:
    int i;
    string s;
public:
    int getI() const { return i; }
    void setI(int i_) { i = i_; }
    string getS() const { return s; }
    void setS(string s_) { s = s_; }
};

class C123 : public I1, public I2, public I3 {
protected:
    int i;
    string s;
    float f;
public:
    int getI() const { return i; }
    void setI(int i_) { i = i_; }
    string getS() const { return s; }
    void setS(string s_) { s = s_; }
    float getF() const { return f; }
    void setF(float f_) { f = f_; }
};

template<class T>
void f1(const T& c1)
{
    cout << "f1:\n";
    cout << "  getI: " << c1.getI() << endl;
}

template<class T>
void f2(const T& c12)
{
    cout << "f2:\n";
    cout << "  getI: " << c12.getI() << endl;
    cout << "  getS: " << c12.getS() << endl;
}

template<class T>
void f3(const T& 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();
}
  1. ? . f2 [C1, C2] [I1, I2].

, .

( ):

#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(const C1& c1)
{
    cout << "f1:\n";
    cout << "  getI: " << c1.getI() << endl;
}

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

void f3(const 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();
}

. , f2 C1 C2 ( C3), , C1, C2. f3. , C12 C23 , C123, C12, C23, C2, f2 f3 getS. , .

a "union" C123, C1, C2, C3

,

#include <string>
#include <iostream>

using namespace std;

class I1 {
public:
    virtual int getI() const = 0;
    virtual void setI(int i) = 0;
};

class I2 {
public:
    virtual string getS() const = 0;
    virtual void setS(string s) = 0;
};

class I3 {
public:
    virtual float getF() const = 0;
    virtual void setF(float f) = 0;
};

class I12 : virtual public I1, virtual public I2 {};
class I23 : virtual public I2, virtual public I3 {};
class I123 : virtual public I12, virtual public I23 {};

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

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

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

class C12 : public I12, public C1, public C2 {};
class C123 : public I123, public C1, public C2, public C3 {};

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

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

void f3(const I123& 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();
}

:

f1:
  getI: 1

=====
f1:
  getI: 12
f2:
  getI: 12
  getS: str12

=====
f1:
  getI: 123
f2:
  getI: 123
  getS: str123
f3:
  getS: str123
  getF: 1.23

=====
0

, . I1, I2 I3 , .

:

#include <iostream>

class I1 {
public:
    virtual void m1() = 0;
    virtual ~I1(){};
};

class C1 : public I1 {
public:
    void m1() override {
        std::cout << "m1() of a C1" << std::endl;
    }
    ~C1(){};
};

class I2 {
public:
    virtual void m2() = 0;
    virtual ~I2(){};
};

class C2 : public I2 {
public:
    void m2() override {
        std::cout << "m2() of a C2" << std::endl;
    }
    ~C2(){};
};

class I3 {
public:
    virtual void m3() = 0;
    virtual ~I3(){};
};

class C3 : public I3 {
public:
    void m3() override {
        std::cout << "m3() of a C3" << std::endl;
    }
    ~C3(){};
};

class I12 : public I1, public I2 {
public:
    virtual ~I12(){};
};

class I23 : public I2, public I3 {
public:
    virtual ~I23(){};
};

class I123 : public I12, public I23 {
public:
    virtual ~I123(){};
};

class C123 : public I123 {
public:
    void m1() override {
        std::cout << "m1() of a C123" << std::endl;
    }
    void m2() override {
        std::cout << "m2() of a C123" << std::endl;
    }
    void m3() override {
        std::cout << "m3() of a C123" << std::endl;
    }
    ~C123(){};
};

void f1(I1 &arg) {
    std::cout << "f1():" << std::endl;
    arg.m1();
}

void f2(I12 &arg) {
    std::cout << "f2():" << std::endl;
    arg.m1();
    arg.m2();
}

void f3(I23 &arg) {
    std::cout << "f3():" << std::endl;
    arg.m2();
    arg.m3();
}

int main() {
    C123 object;
    f1(object);
    f2(object);
    f3(object);
    return 0;
}

:

f1():
m1() of a C123
f2():
m1() of a C123
m2() of a C123
f3():
m2() of a C123
m3() of a C123

, ++ , . , ++ Item 40: . . , " MI" , (.. , , : virtual public ..... - .


Update:

C1, C2 C3 C123 ( , ), :

  • I1, I2, I3, I12, I23, I123
  • class C123 : virtual public I123, public C1, public C2, public C3 m1(), m2() m3().

f1():
m1() of a C1
f2():
m1() of a C1
m2() of a C2
f3():
m2() of a C2
m3() of a C3
0

++ Java, , . , .

- , , . , , . - , . "", , . , , .

, 3 , -, ( ) . , m() I#, ; .

- m, :

class Wrapper {
    I1 slot1;
    I2 slot2;
    I3 slot3;

    Wrapper(i1 = I1.default(), i2 = I2.default(), i3 = I3.default()) {
        slot1 = i1;
        slot2 = i2;
        slot3 = i3;
    }

    void foo() {
        // The default instances don't do anything on m()
        slot1::m();
        slot2::m();
        slot3::m();
    }

}

, , .

, Logger . , cout/cerr , . , , - .

They seem very similar to your selective output of the various data types available in the object.

0
source

Source: https://habr.com/ru/post/1674896/


All Articles