2015-02-25 3 views
0

У меня есть (гарантированный древовидный) каскад классов какЧистые виртуальные функции и множественное наследование

class rock_bottom { 
    ... 
    virtual foo() = 0; 
}; 

class A : rock_bottom {...} 

class intermediate: rock_bottom {...} 

class B : intermediate {...} 

class higher_up {...} 

class C : higher_up {...} 

Я хочу осуществить Foo() в буквенных классах А, В, С. Если мне нужны объявить foo? (Virtual? Pure?) Нужны ли (тривиальные) реализации в промежуточных и средних уровнях среднего уровня?

+0

Если это чистый виртуальный, вы должны реализовать его в каждом не абстрактном классе, который происходит от 'rock_bottom'. В противном случае вы не должны. – Aleph

+0

Вы должны реализовать ту же подпись (виртуальный необязательно). – amchacon

+0

@Aleph: Не каждый класс. Только те, которые вы хотите быть не абстрактными (или базовыми классами тех, прямых или косвенных). –

ответ

1

Каждое переопределение должно быть объявлено в классе, который его реализует; в вашем случае, A, B и C, так как вы говорите, что каждый из них обеспечит переопределение.

Нет необходимости объявлять его в каком-либо промежуточном классе, предполагая, что вы счастливы, что они останутся абстрактными. Они наследуют чистую функцию от rock_bottom, и нет смысла переопределять это с другой чистой функцией.

2

Вопрос:

Я хочу осуществить Foo() в буквенных классах А, В, С. Если мне нужно сделать, чтобы объявить foo? (Virtual Pure?)

Ответ:

Этот вопрос нужно задать в обратном направлении. В каком базовом классе имеет смысл создать интерфейс foo. Давайте рассмотрим некоторые классы, которые вы можете найти в приложении.

struct Shape {}; 
struct Rectangle : public Shape {}; 
struct Square : public Rectangle {}; 
struct Ellipse : public Shape {}; 
struct Circle : public Ellipse {}; 

Это имеет смысл, что все Shape быть в состоянии вернуть их площадь и периметр. Таким образом, вы помещаете их как функции virtual в Shape.

struct Shape 
{ 
    virtual double area() const = 0; 
    virtual double perimeter() const = 0; 
}; 

Перед тем, как можно создать экземпляр подтипа Shape, вы должны реализовать их.

Если вы хотите создать Rectangle, эти функции должны быть реализованы в Rectangle, так как других промежуточных классов нет.

Если вы хотите создать Square, эти функции должны быть выполнены либо в Rectangle, Square, либо в обоих случаях.

Аналогичным образом, если вы хотите создать Ellipse, эти функции должны быть реализованы в Ellipse, так как других промежуточных классов нет.

Если вы хотите создать Circle, эти функции должны быть реализованы либо в Ellipse, Circle, либо в обоих случаях.

Однако, только Rectangle s имеют длину и ширину. Только Ellipse s имеют большой радиус и малый радиус. Не имеет смысла добавлять виртуальные функции-члены в Shape, чтобы вернуть эти значения.

Вопрос:

Нужно ли я (тривиальные) реализации в средних слоях среднего и higher_up?

Ответ:

Нет, вы не знаете. Ответ на предыдущий вопрос должен уточнить, что больше.

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