2015-04-07 1 views
2

J'ai besoin de transmettre, déclarer une classe dans mon dossier d'en-tête, comme ceci:Pourquoi ne puis-je pas transmettre une fonction statique?

class MyStaticClass; 

Je comprends pourquoi on ne peut pas déclarer avant-données membres de cette classe. J'avais l'habitude de penser que vous pouviez cependant déclarer des fonctions. Je voudrais déclarer une fonction statique de cette classe, comme ceci:

class MyStaticClass; 
static int MyStaticClass::AddTwoNumbers(const int a, const int b); 

Cela me donne une erreur de compilation si:

error C2027: use of undefined type 'MyStaticClass' 

Pourquoi cela peut-il pas être fait? Ou y a-t-il un moyen secret de le faire après tout?

+0

Pourquoi? Vous n'avez pas besoin de fournir une déclaration avant d'une fonction de membre de classe. Vous devez juste vous assurer que la définition de classe est dans la portée avant de l'utiliser. – EJP

+0

Dans le projet sur lequel je travaille, je ne peux pas simplement inclure l'en-tête du fichier dont j'ai besoin, pour des raisons. Par conséquent je voudrais simplement le déclarer en avant, et l'avoir lié par l'éditeur de liens. – Yellow

+0

Pour être en mesure de dire 'SomeType :: Anything' vous avez besoin d'une définition complète de' SomeType'. – juanchopanza

Répondre

3

Ceci n'est pas autorisé car cela permettrait à d'autres personnes d'ajouter des fonctions membres à une classe sans même modifier la classe elle-même.

Considérez ceci,

struct X 
{ 
    static void f(float a) { std::cout << a << std::endl; } 
private: 
    static int _data; //inaccessible to non-member 
}; 

X::f(0); //convert 0 (an int) to float, and call X::f(). 

Maintenant, imaginez quelqu'un est venu et l'avant-déclarer la fonction suivante, juste avant d'inclure en-tête qui définit la classe ci-dessus:

static void X::f(int); 

Maintenant, l'appel précédent X::f(0) donnerait erreur de l'éditeur de liens (non résolu nom) car maintenant 0 ne serait pas converti en float, car il ne doit pas comme il y a un déclaré fonction qui accepte un int, bien qu'il ne soit pas défini — pire, s'il est défini, alors vous ne recevrez même pas l'erreur de l'éditeur de liens et vous ne saurez probablement pas facilement qu'une fonction différente est appelée.

Morever. f(int) peut maintenant accéder au membre private_data ainsi que — de cette façon, n'importe qui peut accéder aux membres privés/protégés simplement en ajoutant des fonctions à caprice.