2015-11-21 1 views
0

взгляд на следующий код:Как преобразовать абстрактный класс в нормальный класс без перегрузки чистой виртуальной функции?

class A 
{ 
public: 
    virtual int getN() = 0; 
}; 

class B : public A 
{ 
private: 
    int n = 2; 
public: 
    int getN() { return n; } 
}; 
class C : public A 
{ 
    // do not contain property n, it nolonger need getN(); 
}; 

класса А является абстрактным классом. Теперь у меня есть класс C, полученный от A. Но это не так, как класс B имеет свойство n. Поэтому я не могу перегрузить getN(), а затем класс C является абстрактным классом, который я не могу создать. Итак, если я хочу создать экземпляр класса C, что мне делать?

+1

Сделать 'getN()' приватным в 'C'. –

+1

Поскольку класс A непригоден в качестве базы C, класс A непригоден в качестве базы C. Dang. Я умный. S, M, R, T. –

+1

ваш дизайн неправильный. Базовый класс должен иметь свойства, которые представляют интерес для всех подклассов. В вашем примере вам лучше переместить getN() в B, поскольку он не нужен C – Nandu

ответ

2

Наследование представляет собой «вид» отношений.

Поскольку C не имеет метод getN(), он не может быть «своего рода» A поскольку любой держит ссылку на A имеет право ожидать getN() присутствовать.

У них это право, потому что вы утверждали это, поставив getN в виртуальный виртуальный интерфейс A.

Мораль истории - избегайте наследования, если можете. Предпочитают инкапсуляцию.

+0

Это в значительной степени ключевой момент - если вы не можете предложить договор, * не наследуйте *. – Puppy

0

Вы можете попытаться разделить A на отдельные интерфейсы, что позволяет подклассам выбирать, какие свойства A они хотят наследовать.

Возьмите это, например:

class A 
{ 
public: 
    virtual int getN() = 0; 
}; 

class A1 
{ 
public: 
    virtual int getNum() = 0; 
}; 

class B : public A, public A1 
{ 
private: 
    int n = 2; 
public: 
    int getN() override { return n; } 
    int getNum() override { return 42; } 
}; 
class C : public A1 
{ 
public: 
    virtual int getNum() override { return 1; } 
}; 

Здесь C больше не нуждается в getN() так он наследует только от интерфейсов, которые нужны. Этот шаблон обычно называют interface segregation principle.

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