Страницы

Поиск по вопросам

пятница, 10 января 2020 г.

Как правильно реализовать наследование агрегированных классов?

#cpp #наследование #qt4


Это базовые классы:

class Foo {};
class Bar
{
    QList fooList;
    //функции для работы с fooList;
};


Как сделать так, чтобы можно было написать классы наследники

class FooEx : public Foo {};
class BarEx : public Bar {};
class FooExList : QList {};


и при этом в BarEx тип поля fooList заменить с

QList fooList


на

FooExList fooList?


Никак не могу найти красивое решение.
    


Ответы

Ответ 1



Можно переопределить в классе-наследнике переменную-член базового класса и использовать виртуальные функции. Приведённый ниже код иллюстрирует идею и доказывает её работоспособность: #include class A { public : virtual void whoAmI() const { printf("class A.\n"); } }; class A1 : public A { public : virtual void whoAmI() const { printf("class A1.\n"); } }; class B { private : A a; public : virtual void whoAmI() const { printf("I am class B with member of "); a.whoAmI(); } }; class B1 : public B { private : A1 a; public : virtual void whoAmI() const { printf("I am class B1 with member of "); a.whoAmI(); } }; int main() { B b; B1 b1; B* pb = new B; B* pb1 = new B1; b.whoAmI(); b1.whoAmI(); pb->whoAmI(); pb1->whoAmI(); return 0; } Вывод программы: I am class B with member of class A. I am class B1 with member of class A1. I am class B with member of class A. I am class B1 with member of class A1. Дополнение Можно ещё поступить следующим образом. Хранить в классе Bar не сам объект, а указатель на объект базового класса и в производных классах BarEx создавать объект требуемого класса: class Bar { protected : QList *pFooList = nullptr; Bar(QList* _pFooList) : pFooList(_pFooList) { } public : Bar() : pFooList(new QList()) { } } class BarEx { public : BarEx() : Bar(new FooExList()) { } } Недостаток этого метода в том, что в производных классах указатель pFooList будет иметь тип указателя на базовый класс. Но это легко решается приведением типов.

Ответ 2



В производном классе объявите переменную с тем же именем, но другим типом. class BarEx : public Bar { FooExList fooList } Она перекроет родительскую переменную.

Комментариев нет:

Отправить комментарий