Confused on C ++ Multiple Inheritance

I'm a little new to the more complex C ++ functions. Yesterday I posted the following question, and I learned about virtual inheritance and the scary diamond of death.

Inheriting both an interface and a C ++ implementation

I also learned through other links that multiple inheritance is usually a sign of bad code and that the same results can usually be achieved better without using IM. The question is ... I don’t know what is the best, one-way approach for the next problem.

I want to define an interface for two types of digital points. Digital input point and digital output point. The interface should be thin, only for access to information. Of course, the vast majority of properties are common to both types of digital points. Therefore, for me this is a clear case of Inheritance, not composition.

My interface definitions look something like this:

// Interface Definitions
class IDigitalPoint
{
public:
  virtual void CommonDigitalMethod1() = 0;
};

class IDigitalInputPoint : virtual IDigitalPoint
{
public:
  virtual void DigitialInputMethod1() = 0;
};

class IDigitalOutputPoint : virtual IDigitalPoint
{
public:
  virtual void DigitialOutputMethod1() = 0;
};

And my implementations look like this:

// Implementation of IDigitalPoint
class DigitalPoint : virtual public IDigitalPoint
{
public:
  void CommonDigitalMethod1();
  void ExtraCommonDigitalMethod2();
}

// Implementation of IDigitalInputPoint
class DigitalInputPoint : public DigitalPoint, public IDigitalInputPoint 
{
public:
  void DigitialInputMethod1();
  void ExtraDigitialInputMethod2();
}

// Implementation of IDigitalOutputPoint
class DigitalOutputPoint : public DigitalPoint, public IDigitalOutputPoint 
{
public:
  void DigitialOutputMethod1();
  void ExtraDigitialOutputMethod2();
}

So how could I reformat this structure to avoid MI?

Thanks in advance for your help.

+4
source share
7 answers

" , , " - , , . I* - ( ), Digital*Point .

+7

() .

:

namespace example {
    struct Point { T x; T y; }

    Point read_method();
    void write_method(const Point&)
    void common_method(Point&);
    void extra_common_method(Point&);
} // example

common_method - Point. extra_common_method, , , Point.

+1

, std::basic_iostream.

, , .

, , , .

, ? A DigitalPoint , . A DigitalInputPoint, , ... a DigitalPoint - . ? ? ?

0

,

, !!. , .

0

:

class DigitalPoint
{
public:
  void CommonDigitalMethod1();
  void ExtraCommonDigitalMethod2();
}

// Implementation of IDigitalInputPoint
class DigitalInputPoint
{
public:
  void CommonDigitalMethod1();
  void DigitialInputMethod1();
  void ExtraDigitialInputMethod2();
}

// Implementation of IDigitalOutputPoint
class DigitalOutputPoint
{
public:
  void CommonDigitalMethod1();
  void DigitialOutputMethod1();
  void ExtraDigitialOutputMethod2();
}

:

template <class T>
void do_input_stuff(T &digitalInputPoint){
    digitalInputPoint.DigitialInputMethod1();
}

. , . , , , , .
, vector<IDigitalPoint*>.

0

, 3 ?

class IDigitalPoint
{
public:
    virtual void CommonDigitalMethod1() = 0;
};


enum class Direction : bool { Input, Output };

template <Direction direction>
class DigitalPoint : public IDigitalPoint
{
public:
    void CommonDigitalMethod1() {}
    void ExtraCommonDigitalMethod2() {}

    virtual void DigitialMethod1() = 0;
};

class DigitalInputPoint : public DigitalPoint<Direction::Input>
{
public:
    void DigitialInputMethod1() {}
    void ExtraDigitialInputMethod2() {}

    // This is like DigitialInputMethod1()
    virtual void DigitialMethod1() override
    {}
};

class DigitalOutputPoint : public DigitalPoint<Direction::Output>
{
public:
    void DigitialOutputMethod1() {}
    void ExtraDigitialOutputMethod2() {}

    // This is like DigitialOutputMethod1()
    virtual void DigitialMethod1() override
    {}
};
0

.

If the child classes do not use the functionality from DigitalPoint, you can try using CRTP. This can be confusing if you do not understand CRTP, but it works like a charm when it fits correctly. Living example

0
source

All Articles