Вы не можете явно создавать абстрактный класс внутри другого класса. Но вы можете дать чисто виртуальным функциям абстрактного базового класса определение, которое, в свою очередь, может быть вызвано в производном классе таким образом, который во многом напоминает композицию.
Эффективное программирование на C ++ (второе издание) предполагает, что причина, по которой чистые виртуальные функции в абстрактных классах могут иметь тело (определение), заключается в том, что наследующий класс может обеспечивать реализацию функции, которая вызывает чистую виртуальную версию в своем теле.
Если у вас есть доступ к книге, см. Пункт 36.
Вот пример, который я собрал вместе. Он демонстрирует, как можно получить форму композиции объектов, унаследовав интерфейс от абстрактного класса и используя его реализацию для составления реализации определения функции в производном классе.
#include <iostream>
class P {
public:
virtual void say_hello() = 0;
};
void P::say_hello() { std::cout << "Hello world!" << std::endl; }
class A :public P {
public:
void say_hello() { P::say_hello(); }
};
int main() {
A x;
x.say_hello();
return 0;
}
Результатом будет то, что 'say_hello' класса A будет вызывать чисто виртуальную версию функции P с тем же именем. Поэтому вызов «say_hello ()» для A приведет к выводу «Hello world».
Публичные и защищенные данные члена в абстрактном классе также доступны для производного класса.
#include <iostream>
#include <string>
using namespace std;
class P {
public:
P() { audience = "world"; }
virtual void say_hello() = 0;
protected:
string audience;
};
void P::say_hello() { cout << "Hello " << audience << "!" << endl; }
class A :public P {
public:
void say_hello() { P::say_hello(); }
void say_goodbye() { cout << "Goodbye " << audience << "." << endl; }
};
int main() {
A x;
x.say_hello();
x.say_goodbye();
return 0;
}