Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > А можно ли унаследовать 2 класса


Автор: viii 1.8.2009, 14:17
вот что хотелось бы получить:
Код

class TPin{
protected:
    volatile uint8_t* pin;
    volatile uint8_t* ddr;
    volatile uint8_t* port;
    uint8_t pin_num;

    TPin(volatile uint8_t* base, uint8_t pin_num);
};

class TOutputPin: public TPin{
public:
    TOutputPin(volatile uint8_t* base, uint8_t pin_num);
    bool operator = (bool val);
};

class TInputPin: public TPin{
public:
    TInputPin(volatile uint8_t* base, uint8_t pin_num);
    operator bool();
};

class TBidirectionalPin: public TOutputPin, TInputPin{
    enum{
        DirOut,
        DirIn
    };
    TBidirectionalPin(volatile uint8_t* base, uint8_t pin_num, uint8_t dir) : TPin(base, pin_num) { Direction(dir) };
    using TOutputPin::operator =;
    using TInputPin::operator bool;
    void Direction(uint8_t dir);
};


т.е. Bidirectional должен обладать методами Input и Output и добавлять свой метод
ума не приложу, как тут можно поступить.
не хотелось бы наследовать здесь TPin и реализовывать отдельно методы, существующие в TInpuPin и TOutputPin.
возможно, лучше перенести все методы в TPin а в его потомках (TInputPin, TOutputPin и TBidirectionalPin) закрыть доступ к некоторым методам?
только как это сделать?

Автор: zim22 1.8.2009, 14:28
Цитата(viii @  1.8.2009,  14:17 Найти цитируемый пост)
возможно, лучше перенести все методы в TPin а в его потомках (TInputPin, TOutputPin и TBidirectionalPin) закрыть доступ к некоторым методам?только как это сделать?

или через private наследование или через композицию.
***
вот пример с private наследованием:
Код

class Base {
public:  
  void f1() { }
  void f2() { }
};

class Derived1 : private Base {
public:
  void f1() { Base::f1(); }
};

class Derived2 : private Base {
public:
  void f2() { Base::f2(); }
};

***
вот пример с композицией:
Код

class Base {
public:  
  void f1() { }
  void f2() { }
};

class Derived1 {
public:
  void f1() { b_.f1(); }
private:
  Base b_;
};

class Derived2 {
public:
  void f2() { b_.f2(); }
private:
  Base b_;
};

Автор: mes 1.8.2009, 15:36
судя по коду Вам вместо двойного наследования больше подойдет вариант с наследованием общей реализации:

Код

class TPinTemplate
{
    public:
      void input_impl ();
      void common_impl ();
      void output_impl ();
};
// так:
class TInputPin : protected TPinTemplate
{
    public:
       using TPinTemplate::common_impl;
       using TPinTemplate::input_impl;
};
// или так 
class TInputPin : protected TPinTemplate
{
    public:
       void common_iface () { ...; common_impl(); }
       void input_iface ()  { ...; input_impl(); }      
};


Автор: viii 1.8.2009, 21:20
Нравится предпоследний вариант. Может все-таки можно как-то с двойным наследованием?

Автор: mes 1.8.2009, 21:54
Цитата(viii @  1.8.2009,  20:20 Найти цитируемый пост)
Нравится предпоследний вариант. Может все-таки можно как-то с двойным наследованием? 

можно, но зачем ? 

Код

class TPin {
};
class TIncomPin: virtual public TPin {
};
class TOutputPin : virtual public TPin {
};
class BiPin : public TIncomPin, public TOutputPin{
};



Автор: bsa 2.8.2009, 18:26
viii, виртуальное наследование (вариант от mes) это такой костыль, который очень часто показывает, что у тебя что-то не так запроектировано... Другими словами, в твоем случае не было необходимости делить на столько классов.
Нужно было сразу делать Bidirectional. Очень мало случаев, когда может понадобиться функционал, который ты реализуешь.

Как вариант, можно сделать класс для низкоуровневой работы с портом (открыть/закрыть, читать/писать) и еще два, которые работают с этим классом, но вводят дополнительные высокоуровневые методы для чтения и записи соответственно. В этом случае действительно можно безболезненно объединить эти классы в один наследованием. Единственное, что в этом случае будет дублироваться - указатель на класс низкоуровневой работы, но сам объект будет общим.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)