C++ message d'Erreur redéfinition des fonctions
Je suis l'aide de deux piles de mettre en œuvre une file d'attente de la classe. Mon fichier d'en-tête ressemble:
#ifndef _MyQueue_h
#define _MyQueue_h
using namespace std;
template <typename T>
class MyQueue {
public:
MyQueue();
~MyQueue();
void enqueue(T element);
T peek();
void dequeue();
int size();
bool empty();
private:
int count;
stack<T> stk1;
stack<T> stk2;
};
# include "MyQueue.cpp"
# endif
Et mon rpc (mise en œuvre) fichier ressemble à ceci:
#include <stack>
#include "MyQueue.h"
using namespace std;
template <typename T>
MyQueue<T>::MyQueue()
{
count = 0;
}
template <typename T>
MyQueue<T>::~ MyQueue()
{
}
template <typename T>
void MyQueue<T>::enqueue(T element)
{
stk1.push(element);
count ++;
}
(d'autres fonctions omis).
Cependant, l'utilisation de Xcode 4.5, il n'arrête pas de dire que mes fonctions (MyQueue, ~MyQueue, à la file, peek, etc.) sont redéfinies. Quelqu'un peut-il m'aider à clarifier où je l'ai redéfini?
Merci
Vous ne devriez jamais
include
un fichier source (j'.e les fichiers se terminant par .cpp
, .cc
, ou .C
). Aussi, assurez-vous de include
le fichier d'en-tête dans lequel votre stack
est défini, à moins d'utiliser la STL de la pile.OriginalL'auteur Hayden Coyle | 2013-11-13
Vous devez vous connecter pour publier un commentaire.
Vous essayez quelque chose que je n'aime vraiment pas. C'est un prétexte.
Supprimer
#include "MyQueue.cpp"
, le remplacer par le contenu de MyQueue.cpp, supprimer le fichier MyQueue.cpp. Maintenant, tout fonctionne.Vous tentez de croire que le modèle de code peut être fendu dans le fichier d'en-tête et la mise en œuvre de fichier. Mais parce qu'il ne peut pas vous avoir à tricher, y compris la mise en œuvre de fichier dans le fichier d'en-tête. C'est moins compliqué si vous n'avez pas de triche ou de faire semblant, et se contenter d'un seul fichier, le fichier d'en-tête, avec tout ce qu'il contient.
La raison précise que vous obtenez une redéfinition, c'est que vous êtes de la compilation de votre fichier cpp, qui comprend votre fichier d'en-tête qui comprend votre fichier cpp nouveau. De sorte que le contenu de la rpc fichier est compilé deux fois.
.tpp
fichier pour stocker la mise en œuvre et de l'inclure à la fin de la.hpp
fichier. Approuvez-vous que? Il ne signifie rien pour le compilateur, bien sûr, mais il pourrait sembler "plus propre" pour certaines personnes.J'ai vu ça aussi, il semble inutile pour moi. Quel est le point d'avoir un fichier qui est référencé dans un seul endroit lorsqu'il est inclus dans un autre fichier. De nouveau, pourquoi ne pas simplement avoir un seul fichier? Mais ce sont des questions de style, il peut être fait pour travailler de cette façon, aussi longtemps que vous n'avez pas essayez de compiler le fichier ppt.
Merci. C'est juste une pratique 🙂 j'ai supprimé "#include "MyQueue.h" dans le fichier cpp, mais maintenant cela ne fonctionne toujours pas compiler. Xcode se plaint (à la première fonction il rencontre, le constructeur, le MyQueue<T>::MyQueue()): 1) "Unknown type name 'MyQueue'" et 2)", Devrait unqualified_id." Pensées, pourquoi est-ce donc?
Lire ma réponse, là encore, vous avez fait quelque chose de complètement différent de ce que j'ai suggéré. Fondamentalement, vous devez supprimer le fichier cpp et de mettre tout le code dans le fichier d'en-tête.
OriginalL'auteur john
Le problème est que, lors de la compilation du fichier cpp, le fichier cpp comprend la
.h
fichier, puis le.h
fichier comprend le.cpp
fichier. Ensuite, vous avez deux des copies de la rpc code dans la même "unité de traduction" au même moment.Mais il existe quelques solutions, cela dépend de ce que votre objectif ultime est.
La plus simple et la plus flexible, la solution est simplement de supprimer tous les modèle des trucs dans le
.cpp
fichier et le mettre dans le.h
fichier à la place. Vous pourriez penser que c'est une mauvaise conception, vous avez probablement appris à garder les déclarations et les définitions dans des fichiers séparés, mais c'est la façon dont les modèles sont généralement mises en œuvre. (Bienvenue dans l'étrange et le merveilleux monde des modèles C++!)Mais, peut-être ceux-ci doivent être "privé" des modèles, seulement pour être utilisé à partir d'un
.cpp
fichier. Dans ce cas, la meilleure chose à faire est de simplement passer le tout à partir de la.h
fichier dans le.cpp
fichier.Il existe une troisième approche, qui n'a pas prêté assez d'attention à mon avis. Tout d'abord, retirez le
#include "MyQueue.cpp"
de votre.h
fichier, et de recompiler. C'est tout à fait possible que tout fonctionne pour vous. Cependant, si votre projet a de multiples.cpp
fichiers, vous pouvez obtenir des erreurs d'édition de liens surundefined reference to MyQueue<string> :: MyQueue()
. (oùstring
est remplacé par ce que vous mettez dans votre file d'attente. Ces erreurs d'édition de liens peut être résolu en plaçanttemplate MyQueue<string>;
à la fin du fichier de définitions des modèles (votreMyQueue.cpp
). Cela signifie que vous avez à faire cela une fois pour chaque type que vous envisagez de stocker dans votre file d'attente, mais vous pourriez voir cela comme un avantage, car il vous aidera à vous rappeler de quels types sont pris en charge par votre file d'attente.OriginalL'auteur Aaron McDaid
En C et C++ #include se comporte comme un copier-coller.
Chaque fois que vous voyez
il doit être traité comme si vous littéralement retapé tout le fichier dans un seul endroit.
Donc, si vous compilez MyQueue.cpp le préprocesseur ajoute le contenu de MyQueue.h,
qui lui-même de punaises sur un double de MyQueue.cpp en témoigne
et suit ensuite le contenu natif de MyQueue.cpp.
Donc le résultat de
à l'intérieur de MyQueue.h, est le même que si vous aviez écrit un gros fichier avec le contenu
de MyQueue.h, MyQueue.cpp et MyQueue.cpp de nouveau. (avec l'include de la pile, il y a aussi bien sûr)
C'est pourquoi le compilateur se plaint sur les fonctions se redéfinir.
Le Double inséré à partir de la
peut également contenir la ligne
mais je pense que le comprennent les gardes (ifndef endif) protégé contre les récursive de l'expansion depuis n'
semble pas être un problème.
>
). Cela aidera à prévenir la réponse sera supprimé lors de l'examen pour ne pas répondre à la question qui a été posée.J'étais sous l'impression que, les réponses qui permettent de résoudre le problème sous-jacent, le demandeur a compter de réponses. J'ai ajouté ma réponse parce que j'avais peur que les gens viennent à cette page, prise de loin la seule solution était d'inclure tout le code dans un fichier et je n'ai pas vu l'un d'introduire cette approche exacte. Mais depuis que je suis encore la construction de ma comprendre de la SORTE, je vais faire confiance à votre jugement. Je n'ai pas l'esprit de la suppression de la réponse, sauf si vous pensez qu'il serait plus utile de laisser la barre latérale.
Vrai, des réponses qui permettent de résoudre le problème sous-jacent sont beaux. Cependant, si c'est le cas, vous n'avez pas, il est très clair (le fait qu'il n'était pas clair, c'est pourquoi j'ai commenté au lieu de marqué votre réponse). La meilleure approche est de mettre le la question qui a été posée en haut de la réponse (préfixé par
>
) et ensuite de s'attaquer immédiatement. Pas besoin de faire de la poste une barre latérale. Dans ce cas, vous pourriez dire quelque chose comme "vous n'avez pas nécessairement besoin de le faire.." le Rendre facile pour les évaluateurs à comprendre à qui vous vous adressez l'OP directement (même si vous êtes aussi se référer à d'autres réponses).Je peux le faire, je vais essayer de le modifier, et si vous vouliez bien me donner de la rétroaction sur si c'est mieux.
BTW pour postes sont commandés par upvotes, qui peuvent changer au fil du temps, afin d'utiliser le mot "au-dessus" pour faire référence à une autre réponse n'est pas appropriée. Au lieu de cela, vous devriez avoir un lien à l'autre réponse à l'aide de la
share
lien ci-dessous.OriginalL'auteur NeoGeetz
lorsque vous incluez quelque chose, il remplace le fichier inclus avec le code de l'intérieur, de sorte lorsque vous appelez
#include "MyQueue.cpp"
il le remplace par le fichier cpp, alors votre fichier cpp redéfinit.
Se débarrasser de la ligne permettra de le corriger.
cette réponse n'était pas très clair au sujet de la ligne à supprimer. Vous pouvez peut-être juste supprimer
# include "MyQueue.cpp"
à partir du fichier d'en-tête. Si vous êtes déterminé à garder ces deux fichiers séparément, alors vous devriez réinsérez le#include "MyQueue.h
dans le fichier cpp.Merci Aaron McDaid!
OriginalL'auteur XenoZergNid