c++ char * Initialisierung im Konstruktor
Ich bin nur neugierig, ich will wissen, was hier Los ist:
class Test
{
char * name;
public:
Test(char * c) : name(c){}
};
1) Warum wird nicht Test(const char * c) : name(c){}
Arbeit? Da char * name
ist nicht const? Aber was ist mit diesem:
main(){
char * name = "Peter";
}
name
ist " char*", aber "Peter"
ist const char*, richtig? Also, wie funktioniert, die Initialisierung funktioniert?
2) Test(char * c) : name(c){ c[0] = 'a'; }
- dies das Programm stürzt ab. Warum?
Sorry für meine Unwissenheit.
Was meinst du
ungültige Konvertierung von const char* nach char*
Auf praktischer Hinweis, was Sie wollen, statt ist
dies ist für eine Prüfung, ich denke nicht, dass wir verwenden dürfen, std::string, weil es nicht ein Teil des Kurses
name(c)
funktioniert nicht? Definieren Sie "funktioniert".ungültige Konvertierung von const char* nach char*
"Peter"
ist const char[6]
, nicht const char *
.Auf praktischer Hinweis, was Sie wollen, statt ist
std::string name
dies ist für eine Prüfung, ich denke nicht, dass wir verwenden dürfen, std::string, weil es nicht ein Teil des Kurses
InformationsquelleAutor tuks | 2013-09-23
Du musst angemeldet sein, um einen Kommentar abzugeben.
Richtig.
Einen C++ string-literal ist vom Typ
char const[]
(siehe hier, im Gegensatz zu nurchar[]
im C, da es nicht dieconst
Schlüsselwort1). Diese Zuordnung wird als veraltet betrachtet in C++, aber es ist immer noch erlaubt2 für die Abwärtskompatibilität mit C.Welche Sie vorbei an
Test
beim initialisieren? Wenn Sie die übergabe eines string-literal oder einem illegalen pointer, tunc[0] = 'a'
ist nicht erlaubt.1 Die alte version der Programmiersprache C (wie beschrieben in der K&R Buch veröffentlicht im Jahr 1978) nicht die
const
Schlüsselwort. Seitdem ANSI-C mir die Ideeconst
aus C++.2 Valid in C++03, nicht mehr gültig, in C++11.
char* c = "hello"; Test t(c);
oder nurTest t("hello");
beide AbstürzenSie besser Absturz! Das string-literal "Hallo" kann nicht geändert werden, und Sie versuchen, zu überschreiben, seine erste byte mit
'a'
.Es wird ein
const
- Schlüsselwort in C, und immer war AFAIK (es ist sicherlich in C89, und noch in C11.)Seit C89, aber nicht in der original-K&R C. ich vermute, dass ist der Grund, warum das erlaubt ist.
InformationsquelleAutor Eitan T
Umstellung auf
const
ist eine Einbahnstraße, so zu sprechen.Können Sie konvertieren von
T *
zuT const *
implizit.Konvertierung von
T const *
zuT *
erfordert einen expliziten cast. Auch wenn Sie begann ausT *
, dann konvertiertT const *
konvertieren zurück zuT *
erfordert expliziten cast, auch wenn es wirklich nur "wiederherstellen" den Zugang zu Ihnen hatte, um mit zu beginnen.Beachten Sie, dass im gesamten
T const *
undconst T *
sind genau entspricht, undT
steht für "beliebigen Typs" (char
in deinem Beispiel, könnte aber genauso gut etwas anderes wieint
odermy_user_defined_type
).Initialisieren eines
char *
aus einem string-literal (z.B.char *s = "whatever";
) ist erlaubt, obwohl es gegen diese Allgemeine Regel (das literal selbst ist im Grundeconst
, aber Sie erstellen eine nicht-const-Zeiger). Dies ist einfach, denn es gibt viel code, das hängt davon ab, dies zu tun, und niemand war bereit zu brechen, dass code, so haben Sie eine Regel, um es zu ermöglichen. Diese Regel ist mittlerweile veraltet, obwohl, so zumindest in der Theorie einige zukünftige compiler könnte ablehnen code, die davon abhängt.Da das string-literal selbst ist im Grunde
const
, ist jeder Versuch einer änderung führt zu undefiniertem Verhalten. Auf den meisten modernen Systemen, dadurch wird der Prozess beendet wird, weil der Speicher die Speicherung der string-literal markiert 'nur Lesen'. Das ist nicht das einzige mögliche Ergebnis. Nur ein Beispiel, zurück in den Tagen von MS-DOS, es würde oft gelingt. Es könnte noch bizarre Nebenwirkungen, obwohl. Für ein Beispiel, viele Compiler "wusste", dass string-Literale wurden, soll nur gelesen werden, so würden Sie "merge" identische string-Literale. Deshalb, wenn Sie hatte so etwas wie:Würde der compiler haben "fusioniert"
a
undb
zum eigentlich Punkt, an dem gleichen Speicher-so, wenn Sie geänderta
wird, wird diese änderung betrifft auch dieb
, so würde es ausdrucken "Pater" statt "Peter".Beachten Sie, dass die string-Literale müssen nicht völlig identisch sind, für diese zu passieren. Solange eine war identisch mit dem Ende des anderen, Sie könnten zusammengeführt werden:
Vorschrift ein Verhalten nicht sinnvoll, so das Ergebnis war (und ist) einfach nicht definiert.
InformationsquelleAutor Jerry Coffin
Zunächst ist C++ Sie haben
std::string
. Sollten Sie wirklich in Betracht ziehen es.Bezüglich Ihrer Frage,
"Peter"
ist ein char-literal, also es ist unveränderbar und sicher können Sie nicht darauf schreiben. Sie können:const char *
member-variable und initialisieren Sie es wie Sie tunname(c)
erklären"Peter"
alsconst
char *
member-variable und kopieren Sie die Inhalte, z.B.name(strdup(c))
(und denken Sie daran, die Freigabe im Destruktor.InformationsquelleAutor Jack
Richtig.
"Peter" wird in der Regel gespeichert in einem nur-lese-Speicher (tatsächlich, es hängt davon ab, welche Art von Gerät wir sind auf), denn es ist ein string-literal. Es ist undefiniert, was passiert, wenn Sie versuchen, ändern Sie einen string ein literal ist (aber man kann wohl erraten, dass Sie sollten nicht).
Sollten Sie verwenden
std::string
sowieso.InformationsquelleAutor Mohammed Hossain
1a) Rechts
1b)
"Peter"
ist nichtconst char*
istchar*
aber es kann nicht geändert werden. Der Grund ist für die Kompatibilität mit den Zeiten vorconst
gab es in der Sprache. Eine Menge von code, der bereits existiert, sagtechar* p = "fred";
und Sie konnte nicht einfach machen, dass der code illegal über Nacht.2) Kann nicht sagen warum, würde das Programm Abstürzen, ohne zu sehen, wie Sie mit diesem Konstruktor.
"Peter"
ist einchar const[6]
, nicht einchar*
.wenn es
char const[6]
dann ist, wiechar *name = "Peter";
legal?1) wie kommt es dann funktioniert:
Test(const char* c){ name = new char[strlen(c)+1]; strcpy(name,c);}
wenn ich SchreibeTest t("Peter");
, die der Konstruktor erwartet, const char*, aber"Peter"
ist char* ? 2) t-Test("Hallo");Es ist nicht legal (in C++11; es ist legal, aber veraltet in C++03). Ein konformer compiler warnt Sie (in C++03) oder ablehnen, den code (C++11).
Scheint, ich erklärte es richtig für C dann.
InformationsquelleAutor john