简体   繁体   中英

C++ Calling a function from another class

Very new to c++ having trouble calling a function from another class.

Class B inherits from Class A, and I want class A to be able to call a function created in class 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
        }

};

It all looks fine on screen (no obvious errors) but when I try to compile it i get an error C2079 'b' uses undefined class B.

I've tried making them pointers/ friends but I'm getting the same error.

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

This happens for the same reason that functions in C cannot call each other without at least one of them being declared as a function prototype.

To fix this issue we need to make sure both classes are declared before they are used. We separate the declaration from the definition. This MSDN article explains in more detail about the declarations and definitions.

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

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

void A::CallFunction ()
{
    B b;
    b.bFunction();
}

What you should do, is put CallFunction into *.cpp file, where you include Bh

After edit, files will look like:

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...
}

Referencing to your explanation, that you have tried to change B b; into pointer- it would be okay, if you wouldn't use it in that same place. You can use pointer of undefined class(but declared), because ALL pointers have fixed byte size(4), so compiler doesn't have problems with that. But it knows nothing about the object they are pointing to(simply: knows the size/boundary, not the content).

So as long as you are using the knowledge, that all pointers are same size, you can use them anywhere. But if you want to use the object, they are pointing to, the class of this object must be already defined and known by compiler.

And last clarification: objects may differ in size, unlike pointers. Pointer is a number/index, which indicates the place in RAM, where something is stored(for example index: 0xf6a7b1).

class B is only declared but not defined at the beginning, which is what the compiler complains about. The root cause is that in class A's Call Function, you are referencing instance b of type B , which is incomplete and undefined. You can modify source like this without introducing new file(just for sake of simplicity, not recommended in practice):

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();
 }

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

Forward declare class B and swap order of A and B definitions: 1st B and 2nd A . You can not call methods of forward declared B class.

Here's my solution to the issue. Tried to keep it straight and simple.

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

You can also have a look at the curiously recurring template pattern and solve your problem similar to this:

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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM