Was genau ist der Unterschied zwischen INITIALISIERUNG und ZUWEISUNG?
PS: Wenn möglich, geben Sie bitte Beispiele in C und C ++ an.
Tatsächlich war ich durch diese Aussagen verwirrt ...
C ++ bietet eine weitere Möglichkeit zur Initialisierung von Elementvariablen, die es uns ermöglicht, Elementvariablen beim Erstellen und nicht erst danach zu initialisieren. Dies geschieht durch Verwendung einer Initialisierungsliste. Die Verwendung einer Initialisierungsliste ist der impliziten Zuweisung sehr ähnlich.
Oh mein Gott. Initialisierung und Zuordnung Nun, das ist sicher Verwirrung!
Um zu initialisieren ist gebrauchsfertig. Und wenn wir über eine Variable sprechen, heißt das, dass der Variablen einen ersten, nützlichen Wert gibt . Und eine Möglichkeit dazu besteht in der Verwendung einer Zuweisung.
Es ist also ziemlich subtil: Zuweisung ist eine Möglichkeit, eine Initialisierung durchzuführen.
Die Zuweisung funktioniert gut zum Initialisieren z.B. ein int
, aber es funktioniert nicht gut zum Initialisieren z.B. ein Code%. Warum? Weil das Objekt std::string
mindestens einen Zeiger auf dynamisch zugewiesenen Speicher enthält und
Wenn das Objekt noch nicht initialisiert wurde, muss dieser Zeiger so eingestellt werden, dass er auf einen richtig zugewiesenen Puffer zeigt (Speicherblock, um den Inhalt der Zeichenfolge zu speichern), aber
Wenn das Objekt bereits initialisiert wurde, muss eine Zuweisung möglicherweise den alten Puffer freigeben und einen neuen zuweisen.
Also muss sich der Zuweisungsoperator std::string
offensichtlich auf zwei verschiedene Arten verhalten, abhängig davon, ob das Objekt bereits initialisiert wurde oder nicht!
Natürlich verhält es sich nicht auf zwei verschiedene Arten. Bei einem std::string
-Objekt wird die Initialisierung stattdessen von einem -Konstruktor übernommen. Sie können sagen, dass der Job eines Konstruktors darin besteht, den Speicherbereich zu nehmen, der das Objekt darstellt, und die beliebigen Bits dort in etwas zu ändern, das für den Objekttyp geeignet ist, was einen gültigen Objektstatus darstellt.
Diese Initialisierung von rohen Speicher sollte idealerweise einmal für jedes Objekt vor allen anderen Operationen auf dem Objekt ausgeführt werden.
Und die C ++ Regeln garantieren dies effektiv. Zumindest so lange, wie Sie nicht sehr niedrige Einrichtungen verwenden. Man könnte das als C ++ Konstruktionsgarantie bezeichnen.
Das heißt also, wenn Sie
tun %Vor%Dann machst du einfache Konstruktion aus dem rohen Speicher, aber wenn du es tust
%Vor% Dann konstruieren Sie zuerst std::string
(mit einem Objektstatus, der eine leere Zeichenfolge darstellt) und weisen dann diesem bereits initialisierten s
zu.
Und das erlaubt mir endlich, Ihre Frage zu beantworten. Aus der Sicht der sprachunabhängigen Programmierung ist vermutlich der erste nützliche Wert derjenige, der zugewiesen wird, und so sieht man in dieser Ansicht die Zuweisung als Initialisierung. Auf der technischen C ++ - Ebene wurde die Initialisierung jedoch bereits durch einen Aufruf des Standardkonstruktors von s
vorgenommen, so dass man auf dieser Ebene die Deklaration als Initialisierung und die Zuweisung als nur eine spätere Wertänderung ansieht.
Also, besonders der Begriff "Initialisierung" hängt vom Kontext ab!
Wenden Sie einfach einen gesunden Menschenverstand an, um herauszufinden, was Someone Else wahrscheinlich meint.
Prost & amp; hth.,
Im einfachsten Sinne:
%Vor%Für eingebaute Typen ist es relativ unkompliziert. Für benutzerdefinierte Typen kann es komplexer werden. Werfen Sie einen Blick auf diesen Artikel.
Zum Beispiel:
%Vor%Initialisierung erstellt eine Instanz (eines Typs) mit einem bestimmten Wert.
%Vor%Zuweisung soll einer bereits erstellten Instanz (vom Typ) einen Wert geben.
%Vor%Was ist der Unterschied zwischen Initialisierung und Zuweisung im Konstruktor? & amp; amp; Was ist der Vorteil?
Es gibt einen Unterschied zwischen dem Initialisieren eines Members mithilfe der Initialisierungsliste und dem Zuweisen eines Werts innerhalb des Konstruktorhauptteils.
Wenn Sie Felder über die Initialisierungsliste initialisieren, werden die Konstruktoren einmal aufgerufen.
Wenn Sie die Zuweisung verwenden, werden die Felder zuerst mit Standardkonstruktoren initialisiert und dann (über den Zuweisungsoperator) mit den tatsächlichen Werten neu zugeordnet.
Wie Sie sehen, gibt es einen zusätzlichen Aufwand für die Erstellung & amp; Zuweisung in letzterer, die für benutzerdefinierte Klassen erheblich sein kann.
Für einen Integer-Datentyp oder POD-Klassenmitglieder gibt es keinen praktischen Overhead.
Ein Codebeispiel:
%Vor%Im obigen Beispiel:
%Vor%Dieses Konstrukt wird in C ++ als Member Initializer List bezeichnet.
It initialisiert ein Mitglied param_
auf einen Wert param
.
Wann verwenden Sie HAVE TO
die Initialisierungsliste des Mitglieds?
Sie werden (eher gezwungen) eine Memberinitialisierungsliste verwenden müssen, wenn:
Ihre Klasse hat ein Referenzmitglied
Deine Klasse hat ein const Mitglied oder
Ihre Klasse hat keinen Standardkonstruktor
In C ist die allgemeine Syntax für die Initialisierung mit {}
:
Der Name für S
heißt "designed initializers" und ist erst ab C99 verfügbar.
0
für den entsprechenden Typ. double r = { 1.0
};
0
, nämlich { 0 }
. Diese {}
-Syntax kann nicht direkt für die Zuweisung verwendet werden, aber in C99 können Sie stattdessen zusammengesetzte Literale verwenden wie
Also zuerst ein temporäres Objekt auf dem RHS erstellen und dieses Ihrem Objekt zuweisen.
Eine Sache, die noch niemand erwähnt hat, ist der Unterschied zwischen der Initialisierung und der Zuweisung von Klassenfeldern im Konstruktor.
Betrachten wir die Klasse:
%Vor% Was wir hier haben, ist ein Konstruktor, der Thing::num
auf den Wert 5 initialisiert und 'a' an Thing::c
zuweist. In diesem Fall ist der Unterschied gering, aber wie bereits gesagt, wenn Sie in diesem Beispiel für einige beliebige Klassen int
und char
ersetzen würden, würden wir über den Unterschied zwischen dem Aufruf eines parametrisierten Konstruktors gegenüber einem folgenden Standardkonstruktor sprechen von operator=
function.