2010-05-01 14 views
1

J'ai une hiérarchie de classes et j'écris une fonction virtuelle. Disons qu'il ya trois classesC++ Déclaration avant pour la fonction virtuelle

class A { virtual A* test(); }; (File A.h) 

class B : public A { virtual C* test(); }; (File B.h) 

class C : public A {}; (File C.h) 

Maintenant, est-il possible pour moi d'éviter d'inclure dans C.hB.h, en faisant une sorte de déclaration avant en disant que C est une sous-classe de A?

Merci, Gokul. C/C++ fait la distinction entre les types complets et les types incomplets

+0

Tout client de B aurait besoin de C.h de toute façon. Regardons de plus près votre situation. – Ozan

Répondre

1

Vous pouvez dire au compilateur que trois choses, de trois façons différentes, sur une classe C:

  • Qu'il existe. Vous faites cela en déclarant à l'avance la classe.
  • Comment est-il structuré. Vous faites cela en déclarant la classe.
  • Comment il se comporte. Vous faites cela en définissant les fonctions membres de la classe.

Si vous voulez dire au compilateur ce dont la classe dérive, alors vous parlez de la façon dont la classe est structurée. Vous devez ensuite montrer au compilateur la déclaration de la classe, il n'y a pas d'autre moyen. Pourquoi le besoin de ne pas inclure C.h dans B.h?

1

Si vous en avant-déclariez class C comme ceci:

class C; 

Il sera disponible en tant que type incomplet, ce qui signifie que vous pouvez déclarer un pointeur vers elle. Cependant, vous ne pouvez pas le sous-classer tant que C n'est pas entièrement déclaré, car C est un type incomplet à ce stade.

Vous pouvez utiliser class C en ligne où vous utiliseriez simplement C. Ce que vous voulez est:

class B : public A { virtual class C* test(); }; 
+0

Je pense que vous n'avez pas remarqué que la fonction virtuelle de la classe A contient un type de retour A *. Donc, à moins que je dis que C est une sous-classe de A, cela n'aura aucun sens (je ne veux pas sous-classer C). Si vous pensez avoir répondu à ma question, pouvez-vous être plus clair? – Gokul

+0

@Gokul: Je suppose que vous devrez inclure "c.h". En tout cas, cela ressemble un peu à une odeur de design. – UncleBens

+0

@UncleBens: Moi aussi je pense que c'est le seul moyen. Mais juste pensé à vérifier. – Gokul

0

Il n'y a aucune raison de préciser B :: test() en retour d'un C * parce qu'un * C sera toujours baissés à A * et tout client faisant une utilisation correcte de l'interface à A attendra un A *. Si les clients de B n'attendent que C *, ils doivent soit appeler une fonction différente, soit prendre la responsabilité de s'assurer que les A * renvoyés retournent dans un C * en utilisant dynamic_cast.

Il est également très bien de déclarer la classe C avant la classe A et d'avoir A :: test() retourner un C * - le sous-classement ne fait aucune différence lors de la déclaration de pointeurs sur des types incomplets dans ce cas.