您好我有以下代码 -
class A{
public:
A(){
cout << "In A CTR" << endl;
}
virtual void buildTree() = 0;
void print(){
cout << "int A print This = " << this << endl;
}
};
class B{
public:
B(){
cout << "In B CTR" << endl;
}
virtual A* getBuilder() {
cout << " In B getBuilder , this = " << this << endl;
return NULL;
}
virtual void hell(){
cout << "In B hell This =" << this << endl;
}
void print(){
cout << "in B print This = " << this << endl;
}
B* add(B* child){
cout << "In B add , This = " << this <<endl;
}
};
class C : public A, public B{
public:
C(){
cout << "In C CTR" << endl;
}
A* getBuilder() {
cout << "In C getBuilder , this = " << this << endl;
return this;
}
void print(){
cout << "In C print This = " << this << endl;
}
};
class D : public C{
public:
D(){
cout <<"In D CTR" << endl;
}
void buildTree(){
cout << "buildTree in D , This = " << this << endl;
B *b = NULL;
add(b);
}
void print(){
cout << "In D print This = " << this << endl;
}
};
int main() {
B *root = new D();
root->getBuilder()->buildTree();
return 0;
}
我得到以下输出:
在C getBuilder中,this = 0x7f9aa0500100
在D中的buildTree,this = 0x7f9aa0500100
在B中添加this = 0x7f9aa0500108
我无法弄清楚为什么调用add()
中的class B
。这是我的理解。请纠正我。
root
是B
类型的指针,指向D
。
因此,当调用root->getBuilder()
时,它会调用class C
中的虚函数,该函数返回类型为A*
的指针。
所以,现在root->getBuilder()
返回一个指向D的A类指针。
因此root->getBuilder()->buildTree()
能够在D中调用buildTree。
但是在class D
中的buildTree中,我们调用了class B
中定义的add。
我们如何调用它,因为指针类型为A
且对B
函数不了解。
感谢任何帮助。
由于
答案 0 :(得分:1)
这似乎是个问题:
但是在D类的buildTree中,我们调用了已定义的add 在B类中,我们如何调用它,因为指针类型是A. 并且不应该对B,函数一无所知。
在指针类型buildTree
上调用A*
,其中buildTree
被标记为虚拟,将在D*
给定root
上调用buildTree类型D
。因此add
可以使用D
,因为D
可以访问公共,受保护的方法是超类。
原始代码示例不必要地复杂化。可以通过以下代码检查相同的原理:
A *root = new D();
root->buildTree();
答案 1 :(得分:1)
你拥有的基本上是这个(非常简化):
struct B
{
B* add(B*)
{
std::cout << "B::add\n";
}
};
struct C : B
{
// Nothing relevant
};
struct D : C
{
void buildTree()
{
add(NULL);
}
};
int main()
{
D root;
root.buildTree();
}
班级D
是 C
。课程C
是 B
。这意味着D
也是 B
。因此D
具有成员函数add
。
如果您可以从add
成员函数调用D
,则指针和间接是红色鲱鱼。
我认为我现在看到了问题,而且是关于班级向全世界展示的界面。
再次使用基本和简化的示例:
struct A
{
void funA();
}
struct B
{
// Nothing relevant
};
struct C : A, B
{
// Nothing relevant
};
然后通过
B* p = new C;
有效。但即使指针p
指向C
的对象(也是A
),它也没有A
的接口 (或C
),只有B
。
如果您想使用A
或C
中的功能,则必须使用向下投射将其转换为正确的类型:
static_cast<D*>(p)->funA(); // Cast to the type `p` *really* is