2017-01-04 1 views
1

Ich habe eine Frage von einem meiner Schüler bekommen, in der ich gefragt habe, warum der folgende Code zu einem mysteriösen Ergebnis führt.Hinweis für Anfänger, wie man Bugs mit Überlastung des Bedieners vermeiden kann

Code:

#include <iostream> 

int main() { 
    char op = '+'; 
    int num = 9; 
    std::string res = 
     "a const char* concatenated with a char and std::string " 
        + op + std::to_string(num); 
    std::cout << res << std::endl; 
} 

Nun, er erwartet zu bekommen: a const char* concatenated with a char and std::string + 9 und konnte nicht verstehen, warum er gerade std::string 9 bekommt. Es ist klar, dass das Problem sofort auftauchen würde, wenn es sich um einen Funktionsaufruf und nicht um einen Operator handelt.

Irgendwelche Ratschläge, die ich Novizen geben kann, wie man solche Wanzen mit Operatorüberladung vermeidet?

+0

Leider ist banal, aber die meisten Menschen (mich eingeschlossen) sollte eine Überlastung des Bedieners überhaupt vermeiden, es sei denn, es ist sehr klar, was vor sich geht. Sie haben das kanonische Beispiel, warum Sie diesem Rat hier folgen sollten. – JimmyNJ

+0

@JimmyNJ hier ist kein benutzerdefinierter Operator überladen, und tatsächlich ist das Problem auf einen nicht überladenen Operator zurückzuführen ('+' mit eingebauten Operanden) –

+0

Aber hast du dem Schüler erklärt, warum er die Ergebnisse hat, die er gemacht hat? '+' ist linksassoziativ, also wird versucht, C-String-Literal + char zu verwenden, was bedeutet, dass der C-String-Array-Punkt um 'int ('+')' erweitert wird. – greatwolf

Antwort

2

"a const char* concatenated with a char and std::string " ist ein const char[] Literal, kein std::string. Das Hinzufügen einer Ganzzahl (char ist eine kleine Ganzzahl) zu einem C-artigen Array generiert einen temporären Zeiger, der auf dieses Array am nummerierten Offset zeigt.

Allgemeine Hinweise, um diese Art von Problem zu vermeiden: Vermeiden Sie die Verwendung von Arrays im C-Stil (einschließlich String-Literalen im C-Stil).

Sie können eine C++ Stringliteral verwenden:

using namespace std::string_literals; // need once in the code 

std::string res = 
    "a const char* concatenated with a char and std::string "s 
       + op + std::to_string(num); 

Note der s am Ende des wörtlichen. Sie benötigen #include <string> - das ursprüngliche Programm sollte das auch gehabt haben.


Wenn Sie einen alten Compiler verwenden, die nicht std::string Literale dann einen String unterstützt den Aufbau kann auch durch Streaming in einen Speicherpuffer durchgeführt werden:

std::ostringstream buffer; 
buffer << "bla bla bla" << op << num; 
std::string res = buffer.str(); 
Verwandte Themen