基类需要引用尚未构造的派生类成员
Base class needs reference to derived class member not yet constructed
有没有办法确保通过引用传递给基类的派生类创建的对象已经构造好并且仍然具有继承性
这就是问题的基础:
class ClassA : public ClassA_Base {
public:
ClassA(int maxSize = 4000)
: ClassA_Base(xClassB_Object),
xClassB_Object(maxSize) {};
private:
ClassB xClassB_Object;
};
这是我能找到的最接近的答案。但他们并没有试图使用继承:如何防止使用尚未构造的类成员?
第1版:我实现了Sam Varshavchik的解决方案。
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()
/EDIT 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);
}
在C++中,基类总是在构造派生类的任何部分之前构造。没有例外,没有变通办法,没有其他选择。在基类被完全构造并且其构造函数(如果有的话(返回之前,派生类的任何部分都不存在。这是基本的C++。
但是
C++的另一个基本部分是多重继承,在多重继承的情况下,所有基类总是按声明顺序构造(我忽略了虚拟继承,这增加了一些与此无关的额外复杂性(。
这几乎是您可以使用的唯一工具,用于调整构建顺序。但这一点可以谨慎使用,以利于您。例如,代替第一个示例中显示的代码:
class ClassA : private ClassB, public ClassA_Base {
public:
ClassA(int maxSize = 4000)
: ClassB{maxSize},
ClassA_Base{static_cast<ClassB &>(*this)}
{
}
};
您不是让ClassB
成为ClassA
的私人成员,而是私下从中继承;然后将对它的引用传递给CCD_ 3的构造函数。首先构造完整的ClassB
,然后对ClassA_Base
进行引用
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 如何使用基类指针引用派生类成员
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 在 C++ 中用派生类型重写成员函数
- 如果基类包含双指针成员,则派生类的构造函数
- 在派生类中绑定非静态模板化成员函数
- 为什么基指针可以访问虚拟函数中的派生成员变量
- 在销毁派生成员之前,在破坏者中调用共同功能
- 带有派生成员的基类的独特指针
- 为什么基类对象的私有成员仍然从派生成员中分配
- 派生成员函数指针的多态性
- 派生成员和重载Ostream运算符
- 通过指向派生类的指针访问派生成员变量
- 在构造过程中是否有一种简洁的方法可以派生成员的类型?
- 如何使用派生类特定的方法:派生类中的派生成员
- 获取从基类指针到具有不同类型的两个派生成员变量的访问权
- 当我使用根据基类定义的成员函数指针时,编译器如何调用派生成员函数?
- 将luabind派生成员调用为协同程序
- C++ POD 结构继承?是否有任何关于派生成员的内存布局的保证