Как я могу реализовать внутренние абстрактные классы-члены в C ++?

Абстрактный класс имеет внутренние виртуальные функции.
Может ли абстрактный класс иметь внутренние виртуальные классы, которые будут реализованы позже?

Я попробовал следующее:

#include <bits/stdc++.h>
using namespace std;

class C1 {
public:
class Child {
int tmp;
virtual int getint() = 0;
};
virtual Child getChild() = 0;
};

class C2: public C1 {
public:
class Child {
int getint()
{
return 10;
}
} c;
Child getChild()
{
return c;
}
};

int main() { return 0; }

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

Однако я получил ошибку:

недопустимый абстрактный тип возврата для функции-члена ‘virtual C1 :: Child C1 :: getChild ()’

Разве я не могу реализовать внутренний абстрактный класс в производных классах, так же, как реализовать виртуальную функцию?

1

Решение

В настоящем коде class C1::Child а также class C2::Child не имеют наследственных отношений. Следовательно, они совершенно не связаны между собой. Даже если вы связываете их с наследованием, то также getChild() не может вернуться Child (значение). Может вернуть либо Child& (ссылка) или Child* (указатель), чтобы сформировать действительный virtual методы с ковариационная. См: Тип возвращаемой виртуальной функции C ++

Такие ошибки легко обнаруживаются при использовании override Спецификатор доступен в C ++ 11.

Не зная точного контекста того, чего вы пытаетесь достичь, возможный код должен выглядеть так:

class C1 {
// ... same
virtual Child& getChild() = 0;
//      ^^^^^^ reference
};

class C2 : public C1 {
//         ^^^^^^ did you miss this?
public:
class Child : public C1::Child {
//                   ^^^^^^^^^ inheritance
int getint() override { return 10; }
} c;
Child& getChild() override { return c; }
};

Также ваше приведенное ниже утверждение выглядит запутанным:

«Ребенок — это абстрактный класс, который будет реализован позже»

подобно virtual методы, классы не имеют таких отношений во время выполнения.
Лучшее значение слова «реализация позже» в контексте класса — это реализация вне тела включающего класса, например:

class Outer { public: class Inner; };
// ...
class Outer::Inner { ... };
2

Другие решения

Теоретически, Abstract Classes используются для создания Interfaces, С помощью Interfacesклиенты требуют требуемой функциональности. Путем определения / реализации Interfacesсерверы выполняют функциональность клиента. Interface/Abstract Class просто план требования / соглашения между клиентом и сервером. Классы, которые реализуют Interface/Abstract Class или выполняет функциональные требования могут быть созданы. Так что может быть много реализации одного и того же Interface/Abstract Class, Теперь для того, чтобы получить доступ ко всем этим различным реализациям одного и того же Interface/Abstract Class в любой момент времени нам нужен обобщенный способ. И этот обобщенный путь через pointer(*) or reference(&) к основному Interface\Abstract Class,

В вашем коде C1::Child этоAbstract Class or Interface,

Так, C1::getChild() может вернуть реализацию Interface/Abstract C1::Child, Но он не может вернуть экземпляр Interface/Abstract C1::Child Сам согласно приведенному выше теоретическому объяснению. И отсюда и ошибка.
Правильный способ заявить C1::getChild() было бы:

  • virtual C1::Child* getChild() = 0; или же
  • virtual C1::Child& getChild() = 0;

Также, C1::Child можно просто рассматривать как class внутри namespace C1, поскольку class также является своего рода namespace с некоторыми ограничениями.

1

Из вашего поста вы, кажется, путаете вещи. Я предлагаю вам перечитать абстрактные классы и попробовать несколько простых примеров.

Ребенок — это абстрактный класс, который будет реализован позже, и я надеюсь
реализованный дочерний элемент может использоваться для определения функции.

Чисто виртуальный метод (virtual int getint() = 0; в вашем примере) не предназначено для реализации «позже». Он предназначен для реализации методом переопределения в производном классе.

Например. если у вас есть

class Child {
virtual int getint() = 0;
};

ты не можешь сделать

class Child {
virtual int getint() { return 10; }
};

ни

int Child::getint() { return 10; }

позже.

Что вы можете сделать, это:

class Derived : public Child
{
int getint() override { return 10; }
};
0
По вопросам рекламы [email protected]