Ceci est mon exemple de code:
#include #include using namespace std; class MyClass { ssortingng figName; public: MyClass(const ssortingng& s) { figName = s; } const ssortingng& getName() const { return figName; } }; ostream& operator<<(ostream& ausgabe, const MyClass& f) { ausgabe << f.getName(); return ausgabe; } int main() { MyClass f1("Hello"); cout << f1; return 0; }
Si je commente #include
je ne reçois aucune erreur du compilateur, je suppose parce que c’est inclus par le biais de #include
. Si je clique avec le bouton droit sur Aller à la définition dans Microsoft VS, ils pointent tous deux vers la même ligne dans le fichier xssortingng
:
typedef basic_ssortingng<char, char_traits, allocator > ssortingng;
Mais quand je lance mon programme, je reçois une erreur d’exception:
0x77846B6E (ntdll.dll) dans OperatorSsortingng.exe: 0xC00000FD: débordement de stack (paramètre: 0x00000001, 0x01202FC4)
- Comment remplacer une partie de chaîne par position?
- Méthodes statiques en C ++
- Comment ai-je obtenu une valeur supérieure à 8 bits dans un entier de 8 bits?
- Comment réparer l’erreur de conversion hors plage datetime2 à l’aide de DbContext et SetInitializer?
- Comment concaténer plusieurs chaînes C ++ sur une seule ligne?
Toute idée de la raison pour laquelle je reçois une erreur d’exécution lors du commentaire #include
? J’utilise VS 2013 Express.
En effet, comportement très intéressant.
Toute idée de la raison pour laquelle je reçois une erreur d’exécution lors du commentaire
#include
Avec MS VC ++ comstackr, l’erreur se produit car si vous n’incluez pas #include
vous n’aurez pas d’ operator<<
défini pour std::ssortingng
.
Lorsque le compilateur essaie de comstackr ausgabe << f.getName();
il recherche un operator<<
défini pour std::ssortingng
. Comme il n'a pas été défini, le compilateur recherche des alternatives. Il y a un operator<<
défini pour MyClass
et le compilateur essaie de l'utiliser, et pour l'utiliser, il doit convertir std::ssortingng
en MyClass
et c'est exactement ce qui se passe car MyClass
a un constructeur non explicite! Ainsi, le compilateur finit par créer une nouvelle instance de MyClass
et essaie de le diffuser à nouveau dans votre stream de sortie. Cela se traduit par une récursion sans fin:
start: operator<<(MyClass) -> MyClass::MyClass(MyClass::getName()) -> operator<<(MyClass) -> ... goto start;
Pour éviter l'erreur, vous devez #include
pour vous assurer qu'il existe un operator<<
défini pour std::ssortingng
. Vous devez également rendre votre constructeur MyClass
explicite pour éviter ce genre de conversion inattendue. Règle de sagesse: rendre les constructeurs explicites s'ils ne prennent qu'un seul argument pour éviter la conversion implicite:
class MyClass { ssortingng figName; public: explicit MyClass(const ssortingng& s) // <<-- avoid implicit conversion { figName = s; } const string& getName() const { return figName; } };
Il semble que operator<<
for std::ssortingng
soit défini uniquement lorsque
est inclus (avec le compilateur MS) et pour cette raison, tout se comstack, mais vous obtenez un comportement inattendu car operator<<
est appelé de manière récursive à la place de MyClass
de l' operator<<
appel operator<<
for std::ssortingng
.
Cela signifie-t-il que la chaîne
#include
n'est incluse qu'en partie?
Non, la chaîne est entièrement incluse, sinon vous ne pourriez pas l'utiliser.
Le problème est que votre code effectue une récursion infinie. L’opérateur de streaming pour std::ssortingng
( std::ostream& operator<<(std::ostream&, const std::string&)
) est déclaré dans le fichier d'en-tête
, bien que std::ssortingng
soit déclaré dans un autre fichier d'en-tête (inclus à la fois par
et
).
Lorsque vous n'incluez pas
le compilateur essaie de trouver un moyen de comstackr ausgabe << f.getName();
.
Il arrive que vous ayez défini à la fois un opérateur de diffusion en continu pour MyClass
et un constructeur qui admet une std::ssortingng
, de sorte que le compilateur l'utilise (via une construction implicite ), créant un appel récursif.
Si vous déclarez explicit
votre constructeur ( explicit MyClass(const std::ssortingng& s)
) alors votre code ne sera plus compilé, puisqu'il n'y a aucun moyen d'appeler l'opérateur streaming avec std::ssortingng
, et vous serez obligé de inclure l'en-tête
.
MODIFIER
Mon environnement de test est VS 2010, et à partir du niveau 1 ( /W1
), il vous avertit du problème:
warning C4717: 'operator <<': récursif sur tous les chemins de contrôle, la fonction provoquera un débordement de pile d'exécution