11

对 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' uses undefined class B.

我试过让它们成为指针/friends但我得到了同样的错误。

4

7 回答 7

15
    void CallFunction ()
    {   // <----- At this point the compiler knows
        //        nothing about the members of B.
        B b;
        b.bFunction();
    }

发生这种情况的原因与 C 中的函数在没有至少一个被声明为函数原型的情况下不能相互调用的原因相同。

要解决此问题,我们需要确保在使用这两个类之前都已声明它们。我们将声明与定义分开。这篇 MSDN 文章更详细地解释了声明和定义。

class A
{
public:
    void CallFunction ();
};

class B: public A
{
public:
    virtual void bFunction()
    { ... }
};

void A::CallFunction ()
{
    B b;
    b.bFunction();
}
于 2013-01-05T15:37:25.630 回答
4

你应该做的是放入CallFunction*.cpp 文件中,其中包含 Bh

编辑后,文件将如下所示:

乙:

#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
        }
};

B.cpp

#include "B.h"
void A::CallFunction(){
//use B object here...
}

参考您的解释,您已尝试更改 B b;进入指针 - 如果您不在同一个地方使用它,那也没关系。您可以使用未定义类的指针(但已声明),因为所有指针都有固定的字节大小(4),所以编译器没有问题。但它对他们指向的对象一无所知(简单地说:知道大小/边界,而不是内容)。

因此,只要您使用所有指针大小相同的知识,就可以在任何地方使用它们。但是如果你想使用他们所指向的对象,这个对象的类必须已经被编译器定义和知道。

最后澄清:与指针不同,对象的大小可能不同。指针是一个数字/索引,它指示 RAM 中存储某些内容的位置(例如索引:0xf6a7b1)。

于 2013-01-05T15:31:08.773 回答
1

类 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();
 }
于 2013-01-05T15:29:24.013 回答
0

在 A 中,您使用了 B 的定义,直到那时才给出,这就是编译器给出错误的原因。

于 2013-01-05T15:33:34.103 回答
0

前向声明class B和交换顺序AB定义: 1stB和 2nd A。您不能调用前向声明B类的方法。

于 2013-01-05T15:37:19.677 回答
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;
}
于 2021-01-10T18:35:19.417 回答
0

您还可以查看奇怪重复出现的模板模式并解决类似于以下的问题:

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();
}
于 2021-07-29T12:47:05.490 回答