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 の関数が少なくとも 1 つの関数プロトタイプとして宣言されていないと相互に呼び出すことができないのと同じ理由で発生します。

この問題を修正するには、両方のクラスが使用される前に宣言されていることを確認する必要があります。宣言を定義から分離します。この 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、Bhを含む*.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 の Call Function で、B不完全で未定義の type のインスタンス 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

and定義の前方宣言class Bとスワップ順序: 1stと 2nd 。前方宣言されたクラスのメソッドを呼び出すことはできません。ABBAB

于 2013-01-05T15:37:19.677 に答える
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 に答える