別のクラスから関数を呼び出すのに問題がある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
にしようとしましたが、同じエラーが発生しています、
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();
}
すべきことは、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)。
クラス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();
}
aでは、それまで与えられていなかったBの定義を使用しました。そのため、コンパイラーはerrorを与えています。
前方宣言class B
およびA
およびB
定義の交換順序:1番目のB
および2番目のA
。前方宣言されたB
クラスのメソッドを呼び出すことはできません。