c ++很难从另一个类调用函数时遇到问题。
B类继承自A类,我希望A类能够调用在B类中创建的函数。
using namespace std;
class B;
class A
{
public:
void CallFunction ()
{
B b;
b.bFunction();
}
};
class B: public A
{
public:
virtual void bFunction()
{
//stuff done here
}
};
它在屏幕上看起来都很好(没有明显的错误)但是当我尝试编译它时我得到一个错误C2079'b'使用未定义的B类。
我已经尝试过将它们作为指针/ friends
,但我收到同样的错误,
答案 0 :(得分:9)
void CallFunction ()
{ // <----- At this point the compiler knows
// nothing about the members of B.
B b;
b.bFunction();
}
出现这种情况的原因与C中的函数不能相互调用而其中至少有一个被声明为函数原型的情况相同。
要解决此问题,我们需要确保在使用它们之前声明这两个类。我们将声明与定义分开。 This MSDN article更详细地解释了声明和定义。
class A
{
public:
void CallFunction ();
};
class B: public A
{
public:
virtual void bFunction()
{ ... }
};
void A::CallFunction ()
{
B b;
b.bFunction();
}
答案 1 :(得分:3)
您应该做什么,将CallFunction
放入* .cpp文件中,其中包含B.h。
编辑后,文件将如下所示:
#pragma once //or other specific to compiler...
using namespace std;
class A
{
public:
void CallFunction ();
};
class B: public A
{
public:
virtual void bFunction()
{
//stuff done here
}
};
#include "B.h"
void A::CallFunction(){
//use B object here...
}
参考你的解释,你试图改变B b;如果你不想在同一个地方使用它,那就没问题了。您可以使用未定义类的指针(但已声明),因为所有指针都有固定的字节大小(4),因此编译器没有问题。但它对他们所指向的对象一无所知(简单地说:知道大小/边界,而不是内容)。
因此,只要您使用这些知识,所有指针大小相同,您就可以在任何地方使用它们。但是如果你想使用它们所指向的对象,那么这个对象的类必须已经被编译器定义和识别。
最后一点澄清:与指针不同,对象的大小可能不同。指针是一个数字/索引,它表示存储内容的RAM中的位置(例如索引:0xf6a7b1)。
答案 2 :(得分:0)
B类在开头只是声明但不是定义,这是编译器抱怨的内容。根本原因是在A类的调用函数中,您引用的类型为B
的实例b,它是不完整且未定义的。您可以在不引入新文件的情况下修改此类源代码(仅为了简单起见,不建议在实践中使用):
using namespace std;
class A
{
public:
void CallFunction ();
};
class B: public A
{
public:
virtual void bFunction()
{
//stuff done here
}
};
// postpone definition of CallFunction here
void A::CallFunction ()
{
B b;
b.bFunction();
}
答案 3 :(得分:0)
在A中你使用了B的定义,直到那时才给出,这就是编译器给出错误的原因。
答案 4 :(得分:0)
转发声明class B
以及A
和B
定义的交换顺序:第一B
和第二A
。您无法调用前向声明的B
类的方法。
答案 5 :(得分:0)
这是我对这个问题的解决方案。尽量保持简洁。
#include <iostream>
using namespace std;
class Game{
public:
void init(){
cout << "Hi" << endl;
}
}g;
class b : Game{ //class b uses/imports class Game
public:
void h(){
init(); //Use function from class Game
}
}A;
int main()
{
A.h();
return 0;
}
答案 6 :(得分:0)
您还可以查看 curiously recurring template pattern 并解决与此类似的问题:
template<typename B_TYPE>
struct A
{
int callFctn()
{
B_TYPE b;
return b.bFctn();
}
};
struct B : A<B>
{
int bFctn()
{
return 5;
}
};
int main()
{
A<B> a;
return a.callFctn();
}