Très nouveau pour c ++ ayant du mal à appeler une fonction d'une autre classe.
La classe B hérite de la classe A, et je veux que la classe A puisse appeler une fonction créée dans la classe 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
}
};
Tout semble correct à l'écran (pas d'erreurs évidentes) mais quand j'essaye de le compiler, j'obtiens une erreur C2079 'b' utilise la classe B non définie.
J'ai essayé de leur faire des pointeurs/friends
mais je reçois la même erreur,
void CallFunction ()
{ // <----- At this point the compiler knows
// nothing about the members of B.
B b;
b.bFunction();
}
Cela se produit pour la même raison que les fonctions en C ne peuvent pas s'appeler sans qu'au moins l'une d'entre elles ne soit déclarée comme prototype de fonction.
Pour résoudre ce problème, nous devons nous assurer que les deux classes sont déclarées avant d'être utilisées. Nous séparons la déclaration de la définition. Cet article MSDN explique plus en détail les déclarations et définitions.
class A
{
public:
void CallFunction ();
};
class B: public A
{
public:
virtual void bFunction()
{ ... }
};
void A::CallFunction ()
{
B b;
b.bFunction();
}
Ce que vous devez faire, c'est mettre CallFunction
dans le fichier * .cpp, où vous incluez B.h.
Après modification, les fichiers ressembleront à:
#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...
}
Se référant à votre explication, que vous avez essayé de changer B b; en pointeur - ce serait bien, si vous ne l'utilisez pas au même endroit. Vous pouvez utiliser un pointeur de classe non définie (mais déclaré), car TOUS les pointeurs ont une taille d'octet fixe (4), donc le compilateur n'a aucun problème avec cela. Mais il ne sait rien de l'objet vers lequel il pointe (simplement: connaît la taille/limite, pas le contenu).
Donc, tant que vous utilisez la connaissance, que tous les pointeurs sont de la même taille, vous pouvez les utiliser n'importe où. Mais si vous voulez utiliser l'objet, ils pointent vers, la classe de cet objet doit être déjà définie et connue par le compilateur.
Et dernière précision: les objets peuvent différer en taille, contrairement aux pointeurs. Le pointeur est un nombre/index, qui indique l'endroit dans la RAM, où quelque chose est stocké (par exemple index: 0xf6a7b1).
la classe B est seulement déclarée mais pas définie au début, ce dont se plaint le compilateur. La cause première est que dans la fonction d'appel de la classe A, vous faites référence à l'instance b de type B
, qui est incomplète et non définie. Vous pouvez modifier la source comme ceci sans introduire de nouveau fichier (juste pour des raisons de simplicité, non recommandé dans la pratique):
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();
}
dans A, vous avez utilisé une définition de B qui n'est pas donnée jusque-là, c'est pourquoi le compilateur donne une erreur.
Déclarer en avant class B
et l'ordre de swap des définitions A
et B
: 1er B
et 2e A
. Vous ne pouvez pas appeler les méthodes de la classe B
déclarée vers l'avant.