web-dev-qa-db-ja.com

C ++別のクラスから関数を呼び出す

別のクラスから関数を呼び出すのに問題がある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にしようとしましたが、同じエラーが発生しています、

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

これは、Cの関数の少なくとも1つが関数プロトタイプとして宣言されていないと、Cの関数が相互に呼び出せないのと同じ理由で発生します。

この問題を修正するには、両方のクラスを使用する前に宣言する必要があります。定義から宣言を分離します。 このMSDN記事 では、宣言と定義について詳しく説明しています。

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

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

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

すべきことは、CallFunctionを* .cppファイルに入れて、B.hをインクルードすることです。

編集後、ファイルは次のようになります。

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

B.cpp

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

B bを変更しようとしたという説明を参照してください。同じ場所で使用しなくても大丈夫です。すべてのポインターは固定バイトサイズ(4)であるため、未定義のクラスのポインターを使用できます(ただし、宣言済み)。しかし、それが指しているオブジェクトについては何も知りません(単純に:コンテンツではなくサイズ/境界を知っています)。

したがって、すべてのポインターが同じサイズであるという知識を使用している限り、どこでも使用できます。しかし、オブジェクトを使用したい場合は、それらが指しているので、このオブジェクトのクラスは既に定義されており、コンパイラによって認識されている必要があります。

最後の説明:ポインターとは異なり、オブジェクトのサイズが異なる場合があります。ポインターは、何かが格納されるRAM内の場所を示す数値/インデックスです(たとえば、インデックス:0xf6a7b1)。

3
therealszaka

クラス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();
 }
0
Hui Zheng

aでは、それまで与えられていなかったBの定義を使用しました。そのため、コンパイラーはerrorを与えています。

0
Anirudh Kumar

前方宣言class BおよびAおよびB定義の交換順序:1番目のBおよび2番目のA。前方宣言されたBクラスのメソッドを呼び出すことはできません。

0