Есть ли способ убедиться, что объект, созданный производным классом, который передается по ссылке в базовый класс, уже создан и все еще имеет наследование?
Это базовыйвопроса:
class ClassA : public ClassA_Base {
public:
ClassA(int maxSize = 4000)
: ClassA_Base(xClassB_Object),
xClassB_Object(maxSize) {};
private:
ClassB xClassB_Object;
};
Это самый близкий ответ, который я смог найти. Но они не пытаются использовать наследование: как предотвратить использование еще не созданных членов класса?
РЕДАКТИРОВАТЬ 1: Я реализовал решение от Сэма Варшавчика.
class ClassA : private ClassB, public ClassA_Base {
public:
ClassA(int maxSize = 4000)
: ClassB{maxSize},
ClassA_Base{static_cast<ClassB &>(*this)} {}
};
Очевидно, что имена функций, которые я использую, не совпадают с рассматриваемым примером кода, и все уровни AppLevel, производного и базового содержат гораздо больше кода. Мой код теперь обращается к базовым функциям напрямую, а не через xClassB_Object, поэтому я теряю «квалификатор». «Откуда взялась эта функция, которая не имеет ничего общего с функциональностью AppLevel / ClassA?!»
Чтобы попытаться смягчить «двусмысленность», я использую больше уточнений в вызовах. Вместо просто:
ClassB_Action()
Глядя на полный вызов:
this->ClassB_Base::ClassB_Action()
Я удаляю «this->» и использую следующее:
ClassB_Base::ClassB_Action()
/ РЕДАКТ. 1:
Вот более подробная версия вопроса.
У меня есть цепочка классов. Некоторые из них являются рабочими, а некоторые выделяют для рабочих. Это дает наибольшую гибкость при использовании классов.
Мое намерение состоит в том, чтобы пользователь извлекал любой уровень в цепочке без необходимости реализовывать что-либо для поддержки базового класса, кроме вызова конструкторов. Затем используйте функции-члены базового класса напрямую.
Проблема в том, что из-за порядка вызова конструкторов мои объекты не создаются полностью, когда их ссылка передается конструктору базового класса. Я знаю, что могу передать ссылку на этом этапе, но я просто не могу использовать ее в конструкторе базового класса.
Это целая цепочка классов:
ClassB - moves data into memory (does not need ClassA)
ClassA - modifies the data and passes to ClassB
ClassB_Base - Worker (Operates on buffer)
ClassB - Allocator (Creates a buffer)
ClassA_Base - Worker (Operates on data and calls ClassB worker)
ClassA - Allocator (Creates a ClassB)
AppLevelClass - Top layer passing in data
//// ClassB_Base acts on the data
class ClassB_Base {
public:
ClassB_Base(int* pData, int* pIndex, int length)
: xpData(pData),
xpIndex(pIndex),
xLength(length) {}
void ClassB_Action(int* data) {
//// Do ClassB_Action stuff with the data
xpData = xpIndex = &xLength; // Junk code to eliminate compiler warning
}
private:
int* xpData;
int* xpIndex;
int xLength;
};
//// ClassB only allocates a data buffer for use in ClassB_Base
class ClassB : public ClassB_Base
{
public:
ClassB(int maxSize)
: ClassB_Base(new int[maxSize], &xIndex, maxSize) {}
private:
int xIndex;
};
//// ClassA_Base acts on the data and calls ClassB
class ClassA_Base {
public:
ClassA_Base(ClassB_Base& ClassB_Passed_Ref)
: xClassB_Object_Ref(ClassB_Passed_Ref) {}
void ClassA_Action(int *data) {
//// Do some ClassA_Action stuff with the data like sort or filter
xClassB_Object_Ref.ClassB_Action(data);
}
private:
ClassB_Base& xClassB_Object_Ref;
};
//// ClassA only instantiates a class for use in ClassA_Base
class ClassA : public ClassA_Base {
public:
ClassA(int maxSize = 4000)
: ClassA_Base(xClassB_Object),
xClassB_Object(maxSize) {}
private:
ClassB xClassB_Object;
};
Примеры использования:
//// Now using the whole chain
class AppLevelClass1 : public ClassA {
public:
AppLevelClass1(void) {
ClassA_Action(xData);
}
int xData[10];
};
//// Or using part of the chain
class AppLevelClass2 : public ClassB {
public:
AppLevelClass2(void) {
ClassB_Action(xData);
}
int xData[10];
};
//// Or using another part of the chain
class AppLevelClass3 : public ClassB_Base {
public:
AppLevelClass3(void) : ClassB_Base(xBuff, &xIndex, 100) {
ClassB_Action(xData);
}
int xData[10];
int xIndex;
int xBuff[1000];
};
//// Other use cases
int main() {
int data[10];
int index;
AppLevelClass myAppLevelClass;
myAppLevelClass.ClassA_Action(data);
ClassB_Base xClassB_Base(data, &index, 5);
xClassB_Base.ClassB_Action(data);
ClassB xClassB(1000);
xClassB.ClassB_Action(data);
ClassA_Base xClassA_Base1(xClassB_Base);
xClassA_Base1.ClassA_Action(data);
ClassA_Base xClassA_Base(xClassB);
xClassA_Base.ClassA_Action(data);
ClassA xClassA(1000);
xClassA.ClassA_Action(data);
}