2011-12-19 1 views
1

Мне нужно отвлечь много интерфейса от базового класса, сделав его защищенным, но мне также нужен открытый доступ к классу простых предков Object. Могу ли я договориться о dreaded diamond без права на запись/редактирование этих предков и по-прежнему представлять только базовый API, но еще раз обновить API Object?C++ Множественное наследование, видимость базового класса и страшный алмаз. Повторное выставление базового класса предков как общедоступное?

class Object { 
    virtual bool Equals (const Object &obj) const; 
    virtual int GetHashCode (void) const; 
}; 

class ComplicatedOne : public Object { 
    //Lots of funcs I don't want or need. 
}; 

class Line : protected ComplicatedOne, public Object { 
    //Some funcs of ComplicatedOne get re-implemented or called by alias here 
public: 
    virtual bool Equals(const Object &obj) const { 
     return Object::Equals(obj); 
    } 
    virtual int GetHashCode() const { 
     return Object::GetHashCode(); 
    } 
}; 

class Array { 
    void Add (Object &obj); 
    Object *GetAt (int i); 
}; 

main() { 
    Array a; 
    a.Add(new Line()); 
} 

ответ

2

Вы можете использовать композицию.

В качестве участника можно разместить экземпляр ComplicatedOne и разоблачить, что вам нужно.

Этот способ позволяет защитить его, но никогда не будет иметь ситуацию с бриллиантами.

Кроме того, если ComplicatedOne является Object, так Line является Object по наследству, так что вам не нужно снова наследовать.

1

Вы очень расплывчаты в своей реальной проблеме, но для меня это звучит так, как будто вы хотите использовать наследование только для повторного использования кода.
Вы не должны этого делать. Посмотрите на это article.
Мне кажется, что композиция больше того, чего вы хотите. Создайте член вашего ComplicatedOne в своей линейке классов и делегируйте вызовы этому участнику. Тогда вам не нужно наследовать его.

+0

Правда, я собираюсь ОО безумно с наследованием, когда требуется композиция. – John

0
return Object::Equals(obj); 

Это не может скомпилировать, потому что неоднозначна: есть два Object базовых объектов.

Кроме того, переход от Line* к Object* неоднозначно, и неясность не может быть решена до второго Object базового класса (в порядке слева направо базового класса), так что вторая Object база не служит никакой цели, кроме создания сложности.

Непонятно, что вы пытаетесь сделать точно: что представляет класс ComplicatedOne? Почему вы наследуете его, если вы снова переопределите каждую виртуальную функцию Object?

+0

Хотя 'ComplicateOne' содержит' // Множество funcs, которые мне не нужны или нужны. ', У него все еще есть свои возможности. – John

Смежные вопросы