Was sind die oft missverstandenen Konzepte in C++?
Was sind die oft missverstandenen Konzepte in c++?
- ähnlich: stackoverflow.com/questions/75538/hidden-features-of-c
- mehr wie stackoverflow.com/questions/294018/...
- auch ähnlich: stackoverflow.com/questions/174892/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
C++ ist nicht C mit Klassen!
Und es gibt keine Sprache namens C/C++. Alles geht bergab von dort.
c
undc++
sind nicht Umgang mit Szenario. Aber was die Diskussion der hybridisierten C-und C++ - code ist nicht legitim ist falsch.Dass C++ hat automatische Ressourcen-management.
(Die meisten Leute, die behaupten, dass C++ nicht über memory-management versuchen Sie, verwenden Sie new und delete zu viel, nicht zu merken, dass wenn Sie erlaubt C++, zur Verwaltung der Ressourcen selbst, die Aufgabe wird viel einfacher).
Beispiel: (mit einem aus-API, weil ich nicht die Zeit haben, überprüfen Sie die docs jetzt)
auto
Stichwort ist die default storage-Klasse für eine (stack-allokierten) lokale Variablen. Heap-Allokation, wie gekennzeichnet durch die Verwendung dernew
keyword, werden verwendet, um eine Ressource für die manuelle Ressource management. Jedoch allzu oft, ein Programmierer missbraucht dienew
Schlüsselwort und verursachte Speicherlecks; dann werden Sie behaupten, C++ keine automatische Ressourcen-management, wenn Sie gerade es deaktiviert haben.Die kostenlosen Funktionen sind nicht schlecht nur weil Sie nicht innerhalb einer Klasse C++ ist nicht eine OOP-Sprache allein, sondern baut auf einem ganzen Stapel von Techniken.
Ich habe gehört, dass es viele Male, wenn die Leute sagen, dass die kostenlosen Funktionen (die in der namespaces und der Globale namespace) sind ein "Relikt aus C-Zeiten" und sollte vermieden werden. Das Gegenteil ist der Fall. Freie Funktionen erlauben die Entkopplung von Funktionen aus bestimmten Klassen und ermöglichen die Wiederverwendung von Funktionalität. Es ist auch empfehlenswert, nutzen die kostenlosen Funktionen anstelle von member-Funktionen wenn die Funktion nicht zugreifen müssen, um details zur Implementierung - denn diese beseitigen cascading ändert sich, wenn man die Implementierung einer Klasse unter andere Vorteile.
Dies spiegelt sich auch in der Sprache: Die range-basierte for-Schleife in
C++0x
(nächste C++ - version sehr bald veröffentlicht) basiert auf free Funktion aufruft. Es wird begin /end-Iteratoren durch aufrufen der Kostenlose Funktionenbegin
undend
.Den Unterschied zwischen Zuweisung und Initialisierung:
Initialisierung verwendet immer Konstruktoren, Zuweisung immer verwendet operator=
In absteigender Reihenfolge:
Interessanterweise nicht viele Leute wissen die vollständigen details der virtuellen Funktionen, aber scheinen noch in Ordnung zu sein mit der täglichen Arbeit.
delete
ing Zeiger manuell (es sei denn, Sie selbst sind der Umsetzung einer smart-pointer). Daher würde ich sagen, dass sich ein Missverständnis.Der gefährlichste Konzept, das ich gesehen habe, ist, dass es behandelt werden sollten, als C mit einigen addons. In der Tat, mit modernen C++ - Systemen, es sollte behandelt werden wie eine andere Sprache, und die meisten der C++-bashing sehe ich auf der Grundlage der "C mit add-ons" - Modell.
Erwähnen einige Probleme:
Während Sie wahrscheinlich benötigen, um zu wissen, den Unterschied zwischen
delete
unddelete[]
Sie sollte in der Regel schriftlich auch nicht. Verwendung der smart-Pointer undstd::vector<>
.In der Tat, Sie sollten eine
*
nur selten. Benutzen Sie std::string für Zeichenketten. (Ja, es ist schlecht gestaltet. Verwenden Sie es trotzdem.)RAII bedeutet, dass Sie in der Regel nicht haben, um zu schreiben-clean-up-code. Clean-up-code ist schlechter Stil, und zerstört konzeptionelle Lokalität. Als ein bonus, mit RAII (einschließlich smart-Pointer) gibt Ihnen eine Menge von grundlegenden exception-Sicherheit kostenlos. Insgesamt, es ist viel besser als die garbage collection in gewisser Weise.
In der Allgemeinen Klasse, die Daten der Mitglieder sollte nicht direkt sichtbar, entweder durch
public
oder Getter und setter. Es gibt Ausnahmen (wie x und y in einem Punkt-Klasse), aber Sie sind Ausnahmen und sollten als solche betrachtet werden.Und der große: es gibt keine solche Sprache wie C/C++. Es ist möglich, Programme zu schreiben, kompilieren können richtig unter beiden Sprachen, aber solche Programme sind nicht gut C++ und sind in der Regel nicht gut C. Die Sprachen auseinander entwickelt, seit Stroustrup begann die Arbeit an "C with Classes", und sind weniger ähnlich als je zuvor. Mit "C/C++" als Namen einer Sprache ist prima-facie-Beweise dafür, dass der Benutzer nicht weiß, was er oder Sie redet. C++, richtig verwendet, ist nicht mehr wie C als Java oder C# sind.
std::string
ist nicht schlecht konzipiert-es hat einfach nicht die meisten der Funktionen, die als Teil der Signatur. Verwenden STL-Stil algorithmen auf stattdessen. Zu viele C++ - Programmierer betrachtenstd::string
als eine beschissene version einer Java-oder C# - string, und nicht als ein vollwertiges STL-container.std::string
ist schlecht gestaltet ?Den übermäßigen Gebrauch von Vererbung nichts mit Polymorphismus. Die meisten der Zeit, es sei denn, Sie wirklich wollen, verwenden Laufzeit-Polymorphie, Komposition oder statischer Polymorphismus (d.h., Vorlagen) ist besser.
Den statische Schlagwort, kann das drei verschiedene Dinge, je nachdem, wo es verwendet wird.
Arrays sind keine Zeiger
Sind Sie anders. So
&array
ist kein Zeiger auf einen Zeiger, sondern einen Zeiger auf ein array. Dies ist der am meisten missverstandene Konzept in C und C++ meiner Meinung nach. Du musst ein Besuch für alle diejenigen, die SO Antworten, zu sagen, pass 2-d-arrays alstype**
!Hier ist ein wichtiges Konzept in C++, das oft vergessen wird:
Hier sind einige:
const
-ness vs tatsächlicheconst
-ness in Erinnerung. Beim Einsatz desmutable
Stichwort.DANKSAGUNG: vielen Dank für die Korrektur meiner Fehler, spoulson.
EDIT:
Hier mehr:
Gegeben:
welchen Wert hat X?
Die Antwort, die Sie oft hören, ist abhängig von der Ebene des Verständnisses der Spezifikation.
Es ist bedauerlich, dass die standard-Anwendungen 'byte' zu finden, um eine Einheit von Speicher, da viele Programmierer denken, 'byte' als acht bits.
sizeof(char)
ist definiert durch die Sprache, die als standard von C99 zu einem byte). Der "Experte" hört sich wie der Anfänger, für beide macht keinen Sinn, dass Sie verwirrend und letztlich falsch. Die "Mittelklasse" scheint auch ein bisschen verwirrt, aber zumindest nicht speienden Unsinn mit mehr Selbstvertrauen, alssizeof
anderen Datentypen nicht in der Tat davon abhängen, Architektur und/oder compiler. Wies darauf hin, dasssizeof(char)=1
ist die Ausnahme, die sollten einfach genug sein.char
im Gedächtnis (abgesehen davon, dass>=8
). Diesizeof
ein Typ ist bestimmt durch den compiler und nicht die hardware (dachte, es ist sehr ungewöhnlich für Sie nicht zu passen). Wenn ein byte auf, die Maschine ist dargestellt durch 16 bits, dannCHAR_BIT
hat den Wert 16. So einint
dauert bis mindestens 16 bits, wenn im Speicher abgelegt. Wennsizeof(int)=4
, dann bedeutet es, 16*4 bit, aber die einzige Voraussetzung fürsizeof(int) >= sizeof(short) >= sizeof(char) = 1
.sizeof(char)
geht. Das macht die Aussage "in einem system, wo ein char ist acht bit, 32-bit-Wert wird eine sizeof von 4", nicht unbedingt wahr, wie seine mixing-hardware-Implementierungen und compiler-Optionen.sizeof(char)=1
, und auch sonst gibt die Anzahl der bytes zum speichern der Typ. Die Anzahl der bits in einem byte ist in der Regel 8, aber nicht unbedingt. Die tatsächliche Anzahl finden Sie inCHAR_BIT
. Und das ist die ganze Komplexität und Tiefe wissen, das es gibt, um es. Ich würde Zustimmen: "in einem system, wo ein byte ist acht bit, 32-bit-Wert wird (es sei denn, der compiler ist dumm) haben ein sizeof von 4".char
zurückgeben wird 1 unabhängig".C++ ist eine multi-Paradigma-Sprache. Viele Leute assoziieren mit C++ streng mit OOP.
Klassiker unter den Anfänger-c++ von c:
verwechseln
delete
unddelete[]
EDIT:
ein weiterer klassischer Fehler zwischen allen Ebenen der Erfahrung bei der Verwendung von C-API:
statt:
es passiert mir jede Woche. Sie verwenden könnte, streams, aber manchmal muss man sich mit den printf-ähnliche APIs.
Zeiger.
Dereferenzieren von Zeigern. Entweder durch
.
oder->
Adresse mit
&
wenn ein Zeiger benötigt wird.Funktionen, die Parameter by reference durch definieren einer
&
in der Signatur.Zeiger auf Zeiger auf Zeiger
***
oder Zeiger per Referenzvoid someFunc(int *& arg)
Gibt es ein paar Dinge, die Menschen scheinen ständig verwirrt oder haben keine Ahnung:
Zeiger, vor allem, Funktionszeiger und mehrere Zeiger (z.B. int(*)(void*), void***)
Dem Schlüsselwort const und const-Korrektheit (z.B. was ist der Unterschied zwischen const char*, char* const und const char* const, und was bedeutet void Klasse::Element() const; zu bedeuten???)
Memory allocation (z.B. alle Zeiger neu verknüpft, die gelöscht werden soll, malloc/free sollten nicht gemischt werden mit new/delete verwenden delete [] statt delete, warum die C-Funktionen sind immer noch nützlich, (z.B. expand(), realloc()))
Anwendungsbereich (d.h., dass Sie verwenden können, { }, auf Ihre eigenen zu erstellen, die einen neuen scope für Variablen-Namen, anstatt nur als Teil des "ob", etc...)
Switch-Anweisungen. (z.B. nicht zu verstehen, dass Sie optimieren können, wie gut (oder besser in einigen Fällen) als eine Kette von ifs, nicht zu verstehen, fallen durch und seine praktischen Anwendungen (loop unrolling als Beispiel) oder, dass es einen default-Fall)
Aufruf-Konventionen (z.B. was ist der Unterschied zwischen cdecl und stdcall, wie würden Sie implementieren eines pascal-Funktion, warum ist es auch egal?)
Vererbung und Mehrfachvererbung und, mehr im Allgemeinen, die gesamte OO-Paradigma.
Inline-assembler, so ist es in der Regel umgesetzt werden, ist nicht Teil von C++.
sizeof(void *) == sizeof(int)
(oder irgendeine andere Art für diese Angelegenheit, es sei denn, eine tragbare header ausdrücklich garantiert es) in portablen code.Header und implementation files
Dies ist auch ein Konzept falsch verstanden von vielen. Fragen wie was geht in den header-Dateien und warum es bewirkt, dass link-Fehler, wenn die Funktion Definitionen erscheinen mehrfach in einem Programm auf der einen Seite, aber nicht, wenn Sie Klasse Definitionen scheinen mehrere Male auf der anderen Seite.
Sehr ähnlich zu jenen Fragen ist, warum es ist wichtig zu haben header-guards.
Wenn eine Funktion nimmt einen Zeiger auf einen Zeiger, der auf
void*
wird es immer noch tunHabe ich gesehen, dass das Konzept einer void-Zeiger wird Häufig verwechselt. Es wird angenommen, dass, wenn Sie einen Zeiger verwenden Sie ein
void*
, und wenn Sie einen Zeiger auf einen Zeiger verwenden Sie einvoid**
. Aber man kann und sollte in beiden Fällen verwenden Sievoid*
. Einvoid**
nicht über die speziellen Eigenschaften, die einvoid*
hat.Es ist die Besondere Eigenschaft, dass eine
void*
können auch zugewiesen werden, die einen Zeiger auf einen Zeiger, und wenn der Zauber gewirkt wird wieder der ursprüngliche Wert erhalten.void f(void *p) { int **a = (int**)p; *a = some_int_ptr; }
stattvoid f(void **p);
Ich denke, die meisten missverstandenes Konzept über C++ ist, warum es existiert und was sein Zweck ist. Seine oft unter Feuer von oben (Java, C# usw.) und von unten (C). C++ verfügt über die Fähigkeit zum Betrieb in der Nähe der Maschine zum Umgang mit der Komplexität und Abstraktion der Mechanismen zum verwalten von domain-Komplexität.
NULL
ist immer null.Viele verwechseln
NULL
mit einer Adresse, und denke daher es ist nicht unbedingt null, wenn sich die Plattform hat eine andere null-Zeiger-Adresse.Aber
NULL
ist immer null und es wird nicht eine Adresse. Es ist eine null-Konstante integer-Ausdruck, der konvertiert werden können Zeiger-Typen.Speicher Ausrichtung.
std::vector
keine Elemente erstellen, wenn die reserve eingesetzt wirdIch habe es gesehen, dass Programmierer argumentieren, dass Sie zugreifen können, Mitglieder zu Positionen größer als das, was
size()
zurück, wenn Siereserve()
'ed bis zum dass die Positionen. Das ist eine falsche Annahme, aber ist sehr verbreitet unter den Programmierern - vor allem, weil es ist ziemlich schwierig für den compiler zu diagnostizieren Fehler, die im hintergrund die Dinge machen, die "Arbeit".Hehe, das ist eine dumme Antwort: die meisten missverstandenen Sache in C++ zu Programmieren, Fehlermeldungen von g++ als template-Klassen nicht kompiliert werden!
C++ ist nicht C mit string und vector!
C structs VS C++ structs wird oft missverstanden.
C++ nicht zu den typischen Objekt-orientierten Sprache.
Mir nicht glauben? Blick in die STL, weit mehr Vorlagen als Objekte.
Es ist fast unmöglich, auf Java/C# Möglichkeiten zum schreiben der Objekt-orientierten code; es funktioniert einfach nicht.
new
ing, viele Dienstprogramm-Objekte implementieren eine einzige zusammenhängende Funktionalität.new
ed muss gelöscht werden, aber es gibt immer das problem, wer das Objekt besitztQ. E. D.
Wenn Sie darauf bestehen, tun oop mit Zeiger, werden Sie in der Regel große (riesige!) Klassen mit klar definierten Eigentums-Beziehungen zwischen Objekten, um Speicherverluste zu vermeiden. Und dann, selbst wenn Sie das tun, sind Sie bereits zu weit von der Java - /C# - idiom der oop.
Obwohl aus einer puristischen Sicht (z.B. Alan Kay), auch Java und C# verfehlen wahren oop
Einen Zeiger ein iterator, aber ein iterator ist nicht immer ein Zeiger
Dies ist auch ein oft missverstandenes Konzept. Einen Zeiger auf ein Objekt ist ein random-access-iterator: Es kann sein, inkrementiert/dekrementiert durch eine beliebige Menge von Elementen und können gelesen und geschrieben werden. Jedoch, eine iterator-Klasse, die operator-überladungen tun, erfüllen diese Anforderungen auch. So ist es auch ein iterator ist aber natürlich nicht ein Zeiger.
Ich erinnere mich an eine meiner früheren C++ - Lehrer unterrichtete (zu Unrecht), dass Sie einen Zeiger auf ein element eines Vektors, wenn Sie
vec.begin()
. Er wurde tatsächlich angenommen - ohne zu wissen -, dass der Vektor setzt Ihre Iteratoren verwenden von Zeigern.static
Stichwort austauschbar sind". Sie erhalten ähnliche Ergebnisse, aber mit anderen Mitteln, und manchmal sind Sie beides wollen.static
Variablen nicht außerhalb der compilation unit, in der Erwägung, dass anonymous-Namespace-Variablen zu tun. Das kann einen riesigen Unterschied in der shared library name binding Leistung.Ich verstehe immer noch nicht, warum Vektor nicht über eine pop_front und die Tatsache, dass ich kann nicht Sortieren(Liste.begin(), Liste.end())..
Ich weiß, das ist eine alte Frage, aber ich dachte, Objekt-zerschneide - /Ausfall der Polymorphie mit Objekten auf dem stack erwähnenswert. Wenn ich nicht mit C++ für sechs Monate kommt man immer und beißt mich, wenn ich die Sprache wieder.
C++ oder C/C++? Ich würde sagen für beide am meisten missverstandenen Teile der Speicherverwaltung und Zeiger. Erstere, weil die Menschen nicht frei entsprechend (zu früh oder gar nicht!) und das letztere, weil eine Menge Leute einfach nicht "bekommen" Zeiger (entweder auf der pass by reference "Deckmantel" oder im Allgemeinen in so etwas wie eine verkettete Liste).
Warum ist Eine[b] das gleiche wie b[A]?
Ok, nicht wirklich eine Gemeine Frage, aber es kam in eine Klasse, die ich unterrichtete einmal...
Kann für einige Menschen den Unterschied zwischen Vererbung und Polymorphie kann eine verwirrende Konzept.
Sehr schöne Ressource, die ich nicht müde zu fördern - C++ Häufig In Frage Gestellt Wird Antworten
Groß ist, dass die Sprachen nicht zu 100% syntaktisch kompatibel. C++ ist voll link kompatibel zu C, aber C++ - syntax generiert einen complier Fehler in C. Einige Compiler sind nicht wählerisch und Folgen Sie nicht dem C-standard auf den Brief. Die Grundlagen des diese müssen gelernt werden, wenn Sie von einer Sprache in die andere. Hinweis: ich habe nicht Lesen Sie die neuesten C-standard, aber gestern wusste ich, dass dies wahr war.