У меня есть три класса. A, B и C.
Класс B - абстрактный класс.
Класс A должен вызывать функции класса B.
Класс C получен из класса B, а также должен содержать указатель на класс A для вызова функций класса A.
Требует указатель на B. Я знаю, что это может быть достигнуто, если "B является абстрактным классом, его невозможно создать экземпляры". Поэтому я создаю экземпляр C в и использую его для вызова функций B. " сталкиваясь с проблемами при создании экземпляра C.
Класс C нуждается в указателе на класс A для вызова его функций. Как мне это достичь?
//A.h
class A
{
public:
void fun1();
void fun2();
private:
// creating ptr to C because B is an abstract class
C *m_ptrC;
};
//A.cpp
void A::fun1()
{
m_ptrC->fun4();
}
void A::fun2()
{
//some code
}
//B.h
class B
{
public:
//pure virtual function
void fun3() = 0;
void fun4();
};
//B.cpp
void B::fun4()
{
//pure virtual hence C::fun3() gets called
fun3();
}
//C.h
class C:public B
{
public:
//Overridden from B
void fun3();
private:
//Ptr to class A, to call fun
A *ptrA;
};
//C.cpp
//Overridden from B
void C::fun3()
{
ptrA->fun2();
}
Как следует инициализировать ptrC и ptrA? Кроме того, я не уверен в прямом объявлении, и файл включает результат с ошибкой redifinition/неполного типа.
Без фактического кода, который показывает проблему, вот что я думаю:
1: Вы включаете Ch в Ah и Ch в Ah. Это называется циклической зависимостью. Чтобы этого избежать, вам нужно использовать форвардную декларацию. Вы в основном объявляете класс и включаете его заголовок в файл cpp, фактически используя его. Так, например, в Ah вы могли бы:
class C;
class A
{
void fun1();
private:
C *ptrC = new C;
};
И в A.cpp вы можете включить Ch
Другая проблема может отсутствовать, включая защитников в ваших заголовках.
2: передать экземпляр экземпляра (как ref или указатель) в конструктор C. Здесь также используйте форвардную декларацию. Будьте осторожны в отношении срока службы объектов.
У таких циклических зависимостей часто больше проблем, чем того стоит. Попробуйте иметь интерфейс для A (чтобы вы могли передать его на C без включения блока перевода A в C) или использовать функторы, привязанные к экземпляру A.
3: Я действительно не понимаю, почему у вас есть интерфейс к C, если вы не используете полиморфизм, но это может быть из-за отсутствия реального кода.