Heim  >  Artikel  >  Backend-Entwicklung  >  Ausgewählte C++-Interviewfragen, die Sie verstehen müssen

Ausgewählte C++-Interviewfragen, die Sie verstehen müssen

php是最好的语言
php是最好的语言Original
2018-08-06 16:13:212691Durchsuche

Die Essenz von C++-Interviewfragen

1., warum kann das? Werden Konstruktoren nicht als virtuelle Funktion deklariert?

Analyse: Da die virtuelle Funktion die Methode des virtuellen Aufrufs verwendet, bezieht sich der virtuelle Aufruf auf den Arbeitsmechanismus, der es

ermöglicht, nur einen Teil der Informationen zu kennen ermöglicht es uns insbesondere, eine Funktion aufzurufen, die nur die Schnittstelle, aber nicht den genauen Typ ihres Objekts kennt.

Wenn wir jedoch den Konstruktor aufrufen möchten, um ein Objekt zu erstellen, müssen wir den genauen Typ des Objekts kennen.

Der Konstruktor kann also keine virtuelle Funktion sein.

2. Welche Funktionen in C++ können nicht als virtuelle Funktion deklariert werden ?

Analyse: gewöhnliche Funktionen (Nicht-Mitgliedsfunktionen), Konstruktoren, Inline-Mitgliedsfunktionen, statische Mitgliedsfunktionen, Freundfunktionen.

(1) Virtuelle Funktionen werden für Basisklassen und abgeleitete Klassen verwendet, normale Funktionen können nicht verwendet werden

(2) Konstruktoren können nicht verwendet werden, da virtuelle Funktionen virtuelle Aufrufmethoden verwenden,

(3) Das Wesentliche bei Inline-Mitgliedsfunktionen ist die direkte Erweiterung des Codes am Aufrufort

(4) Bei der Vererbung können statische Mitgliedsfunktionen nicht vererbt werden, da sie nur zu einer Klasse gehören keine dynamische Verknüpfung

(5) Die Friend-Funktion ist keine Mitgliedsfunktion der Klasse und kann daher nicht vererbt werden

3 .Was ist der Unterschied zwischen statischen Mitgliedern und nicht statischen Mitgliedern einer Klasse?

Antwort: Es gibt nur ein statisches Mitglied einer Klasse für jede Klasse. Statische Mitglieder werden von Instanzobjekten aller Klassen gemeinsam genutzt Statische Member-Variablen müssen vor der Verwendung initialisiert werden. Auf statische Member-Funktionen und nicht-statische Member-Funktionen kann nur auf statische Member-Variablen zugegriffen werden, da statische Member-Funktionen zu Klassen gehören und diese nicht haben Hinweise. Jedes Objekt hat ein nicht statisches Mitglied.

4 Was ist der Unterschied zwischen Überladen und Umschreiben (überschrieben, manche Bücher nennen es auch „Überschreiben“)?

Überladung: bezieht sich auf das Zulassen mehrerer Funktionen mit demselben Namen, aber die Parameterlisten dieser Funktionen sind unterschiedlich (möglicherweise ist die Anzahl der Parameter unterschiedlich, möglicherweise sind die Parametertypen unterschiedlich). unterschiedlich, vielleicht beide unterschiedlich). Umschreiben: Bezieht sich auf die Methode, mit der eine Unterklasse eine virtuelle Funktion einer komplexen Klasse neu definiert. Aus dem Implementierungsprinzip: Überladung: Der Compiler ändert die Namen von Funktionen mit demselben Namen basierend auf unterschiedlichen Parameterlisten der Funktionen, und dann werden diese Funktionen mit demselben Namen zu unterschiedlichen Funktionen (zumindest für den Compiler). Beispielsweise gibt es zwei Funktionen mit demselben Namen: function func (p: integer): integer; und function func (p: string): integer;. Dann können die vom Compiler geänderten Funktionsnamen wie folgt lauten: int_func, str_func. Die Aufrufe dieser beiden Funktionen wurden zwischen Compilern festgelegt und sind statisch. Mit anderen Worten, ihre Adressen werden zur Kompilierzeit gebunden (frühe Bindung), daher hat Überladung nichts mit Polymorphismus zu tun! Umschreiben: Wirklich relevant für Polymorphismus. Wenn eine Unterklasse die virtuelle Funktion der übergeordneten Klasse neu definiert, ruft der Zeiger der übergeordneten Klasse die zur Unterklasse gehörende Funktion entsprechend den verschiedenen ihr zugewiesenen Unterklassenzeigern auf. Solche Funktionsaufrufe können während der Kompilierung nicht ermittelt werden (Aufruf). Die Adresse der virtuellen Funktion der Unterklasse kann nicht angegeben werden). Daher werden solche Funktionsadressen zur Laufzeit gebunden (späte Bindung)

5 Beschreiben Sie kurz die Unterschiede zwischen Mitgliedsfunktionen, globalen Funktionen und Freundfunktionen.

Memberfunktionen können nur von Objekten aufgerufen werden, die von dieser Klasse instanziiert werden. [Außer statische Mitglieder]

Globale Funktionen können überall aufgerufen werden.

Friend-Funktionen können von Objekten dieser Klasse und Friend-Klassen aufgerufen werden.

Der mit new zugewiesene Speicher wird mit delete gelöscht. Der mit new[] zugewiesene Speicher wird mit delete[] gelöscht, um den Destruktor des Array-Elements aufzurufen. Interne Datentypen haben keine Destruktoren, daher stellt dies kein großes Problem dar. Wenn Sie delete ohne Klammern verwenden, geht delete davon aus, dass es auf ein einzelnes Objekt zeigt, andernfalls geht es davon aus, dass es auf ein Array zeigt.

6. Vor- und Nachteile einer Erbschaft.

Die Klassenvererbung wird zur Kompilierungszeit statisch definiert und kann direkt verwendet werden, um die Implementierung der übergeordneten Klasse einfacher zu ändern. Die Klassenvererbung weist jedoch auch einige Mängel auf. Erstens kann die von der übergeordneten Klasse geerbte Implementierung zur Laufzeit nicht geändert werden, da die Vererbung zur Kompilierungszeit definiert wird. Erschwerend kommt hinzu, dass die übergeordnete Klasse normalerweise zumindest einen Teil des Verhaltens der untergeordneten Klasse definiert und alle Änderungen an der übergeordneten Klasse das Verhalten der untergeordneten Klasse beeinflussen können. Wenn die geerbte Implementierung nicht zur Lösung des neuen Problems geeignet ist, muss die übergeordnete Klasse neu geschrieben oder durch eine andere, besser geeignete Klasse ersetzt werden. Diese Abhängigkeit schränkt die Flexibilität und letztendlich die Wiederverwendbarkeit ein. (Wird hinzugefügt)

7. Was sind die Eigenschaften von C++ (objektorientierte Funktionen)

Kapselung , Vererbung und Mehrfachstatus.

In objektorientierten Programmiersprachen ist die Kapselung eine Funktion, die wiederverwendbare Komponenten zum Aufbau von Softwaresystemen verwendet. Sie unterstützt nicht nur die Wiederverwendbarkeit des Systems, sondern trägt auch dazu bei, die Skalierbarkeit des Systems zu erreichen Das Senden einer gemeinsamen Nachricht beim Aufrufen verschiedener Methoden ist eine Technik zum Verbergen von Informationen und dient dazu, die Definition und Implementierung einer Klasse zu trennen.

8. Wann müssen Sie „konstante Referenzen“ verwenden?

Wenn Sie Referenzen verwenden möchten, um die Effizienz des Programms zu verbessern und die an die Funktion übergebenen Daten vor Änderungen in der Funktion zu schützen, sollten Sie konstante Referenzen verwenden. Konstante Referenzdeklarationsmethode: const type Identifier & reference name = target variable name; 🎜>

a=1; //Richtig

Beispiel 2 string foo( );

void bar(string & s); Formel wird illegal sein:

bar(foo( ));

bar("hello world"

Der Grund ist, dass foo( ) und „hello world“ string Es wird ein temporäres Objekt generiert. In C++ sind diese temporären Objekte vom Typ const. Daher versucht der obige Ausdruck, ein Objekt vom Typ const in einen nicht konstanten Typ zu konvertieren, was unzulässig ist. Referenzparameter sollten als const definiert werden, wenn sie als const

9 definiert werden können. Wofür wird ASSERT() verwendet? >

Antwort: ASSERT() ist ein Makro, das häufig beim Debuggen eines Programms verwendet wird. Wenn das Programm ausgeführt wird, wertet es den Ausdruck in den Klammern aus.

Programm An Es wird ein Fehler gemeldet und die Ausführung abgebrochen. Wenn der Ausdruck nicht 0 ist, fahren Sie mit der Ausführung der folgenden Anweisungen fort. Dieses Makro stellt in der Regel fest, ob offensichtlich illegale Daten im Programm vorkommen. Ist dies der Fall, beendet es das Programm, um schwerwiegende Folgen zu vermeiden und erleichtert auch die Suche nach Fehlern. Beispielsweise sollte die Variable n im Programm nicht 0 sein. Wenn sie 0 ist, kann dies zu einem Fehler führen.

Analyse: ① Ein Verweis auf eine Basisklasse kann auf eine Instanz ihrer abgeleiteten Klasse verweisen ② Ein Zeiger auf eine Basisklasse kann auf eine verweisen Instanz seiner abgeleiteten Klasse

11.

Drei grundlegende Eigenschaften von objektorientiert und einfach Erzählen? ① Kapselung: Abstrakte objektive Dinge in Klassen, und jede Klasse implementiert die Zugriffskontrolle (privat, geschützt, öffentlich) für ihre eigenen Daten und Methoden

② Vererbung: Es gibt drei Implementierungsformen der generalisierten Vererbung:

Implementierungsvererbung (bezieht sich auf die Fähigkeit, die Eigenschaften und Methoden der Basisklasse ohne zusätzliche Codierung zu verwenden)

Visuelle Vererbung (Verwendung untergeordneter Formulare). Erscheinungsbild des übergeordneten Formulars und Implementierungscode) Schnittstellenvererbung (nur Eigenschaften und Methoden werden verwendet, die Implementierung hinkt der Implementierung der Unterklasse hinterher). Die ersten beiden (Klassenvererbung) und die letztere (Objektkombination => Schnittstellenvererbung und rein virtuelle Funktion) stellen zwei Möglichkeiten der Wiederverwendung von Funktionen dar.

③ Polymorphismus: Dies ist die Technik, bei der ein übergeordnetes Objekt einem oder mehreren seiner untergeordneten Objekte gleichgesetzt wird. Nach der Zuweisung kann das übergeordnete Objekt je nach den Eigenschaften der ihm aktuell zugewiesenen untergeordneten Objekte auf unterschiedliche Weise funktionieren . Einfach ausgedrückt ist es ein Satz: Es ist erlaubt, einen Zeiger eines Unterklassentyps einem Zeiger eines übergeordneten Klassentyps zuzuweisen.

Ergänzungsfrage: Welche Rolle spielt Polymorphismus?

Es gibt zwei Hauptmerkmale:

1. Implementierungsdetails ausblenden, damit der Code modularisiert werden kann;

2. für Klassen Achten Sie beim Erben und Ableiten auf den korrekten Aufruf, wenn Sie ein Attribut einer Instanz einer beliebigen Klasse in der Familie verwenden.

12Überladen und umschreiben, manche Bücher heißen auch "überschreiben )?

① Überladen: bedeutet, dass mehrere Funktionen mit demselben Namen existieren dürfen und die Parameterlisten dieser Funktionen unterschiedlich sind (vielleicht ist die Anzahl der Parameter unterschiedlich). die Parametertypen sind unterschiedlich oder beide sind unterschiedlich).

② Umschreiben: Bezieht sich auf die Methode, mit der eine Unterklasse die virtuelle Funktion der übergeordneten Klasse neu definiert.

In Bezug auf Implementierungsprinzipien:

① Überladen: Der Compiler ändert die Namen von Funktionen mit demselben Namen basierend auf unterschiedlichen Parameterlisten der Funktionen, und dann werden diese Funktionen mit demselben Namen verschiedene Funktionen (zumindest für den Compiler). Der Aufruf dieser Art von Funktion wird während der Kompilierung bestimmt und ist statisch. Mit anderen Worten, ihre Adressen werden zur Kompilierzeit gebunden (frühe Bindung), daher hat Überladung nichts mit Polymorphismus zu tun!

② Umschreiben: Hat wirklich etwas mit Polymorphismus zu tun. Wenn eine Unterklasse die virtuelle Funktion der übergeordneten Klasse neu definiert, ruft der Zeiger der übergeordneten Klasse die zur Unterklasse gehörende Funktion entsprechend den verschiedenen ihr zugewiesenen Unterklassenzeigern auf. Solche Funktionsaufrufe können während der Kompilierung nicht ermittelt werden (Aufruf). Die Adresse der virtuellen Funktion der Unterklasse kann nicht angegeben werden). Daher wird eine solche Funktionsadresse zur Laufzeit gebunden (späte Bindung)

13Welche Rolle spielt Polymorphismus?

Es gibt hauptsächlich zwei:

① Ausblenden von Implementierungsdetails, damit der Code modularisiert werden kann; Erweitern des Codemoduls, um eine Wiederverwendung des Codes zu erreichen;

② Wiederverwendung der Schnittstelle: Um den korrekten Aufruf sicherzustellen, wenn ein bestimmtes Attribut einer Instanz einer beliebigen Klasse in der Familie verwendet wird, wenn die Klasse erbt und ableitet.

14, leere Klasse in C++, die standardmäßig generierte Klassenmitgliedsfunktion:

class
{
  public:
    Empty();                         // 缺省构造函数
    Empty(const Empty&);             // 拷贝构造函数
    ~Empty();                        // 析构函数
    Empty& operator=(const Empty&);  // 赋值运算符
    Empty* operator&();              // 取值运算符
    const Empty* operator&() const;  // 取值运算符const
};

15 Welche Methoden der prozessübergreifenden Kommunikation gibt es?

Zu den Methoden der prozessübergreifenden Kommunikation gehören: gemeinsam genutzter Speicher, Pipes (benannte Pipes/unbenannte Pipes), Sockets, Nachrichtenwarteschlangen, Signale, Semaphoren, Speicherzuordnung usw.

16Vier notwendige Bedingungen für einen Deadlock?

Sich gegenseitig ausschließend, Anforderung zur Aufrechterhaltung, unveräußerlich, Schleife.

17 Was ist der Unterschied zwischen statischen und nicht statischen Mitgliedern einer Klasse?

Es gibt nur ein statisches Mitglied jeder Klasse, das zu dieser Klasse gehört. Jedes Objekt des nicht statischen Mitglieds der Klasse hat eine Kopie.

18

Was ist eine flache Kopie? Was ist eine tiefe Kopie?

Flache Kopie bedeutet, dass das Quellobjekt und das Kopierobjekt eine gemeinsame Entität haben, nur die referenzierten Variablen sind unterschiedlich (unterschiedliche Namen). Änderungen an einem Objekt wirken sich auf das andere Objekt aus.

Deep Copy bedeutet, dass das Quellobjekt und das kopierte Objekt unabhängig voneinander sind und Änderungen an einem Objekt keine Auswirkungen auf das andere Objekt haben.

Im Allgemeinen besteht eine flache Kopie darin, den Zeiger dieses Objekts zu kopieren. Eine tiefe Kopie kopiert dieses Objekt.

19, Fensters Mehrere Möglichkeiten, Programmierthreads zu synchronisieren? (Wichtig)

Atomare Sperre, kritischer Abschnitt (Segment), Ereignis, Mutex (Körper), Semaphor, wartebarer Timer

20 Was ist ein „Zitat“? Auf welche Aspekte sollten wir bei der Deklaration und Verwendung von „Referenz“ achten?

Antwort: Eine Referenz ist ein „Alias“ (Alias) einer Zielvariablen. Die Wirkung der Bedienung einer Referenz ist genau die gleiche wie die direkte Bedienung einer Variablen. Denken Sie beim Deklarieren einer Referenz daran, diese zu initialisieren. Nachdem die Referenz deklariert wurde, entspricht sie dem Zielvariablennamen mit zwei Namen, nämlich dem ursprünglichen Namen des Ziels und dem Referenznamen. Der Referenzname kann nicht mehr als Alias ​​für andere Variablennamen verwendet werden. Durch die Deklaration einer Referenz wird keine neue Variable definiert. Dies bedeutet lediglich, dass der Referenzname ein Alias ​​​​des Zielvariablennamens ist. Er ist kein Datentyp an sich, sodass die Referenz selbst keine Speichereinheit belegt der Referenz keine Speichereinheiten zuordnen. Es konnte kein Verweis auf das Array erstellt werden.

21 Was ist der Unterschied zwischen „Referenz“ und Zeiger?

Nachdem ein Zeiger über eine Zeigervariable auf ein Objekt zeigt, wirkt er indirekt auf die Variable, auf die er zeigt. Die Verwendung von Zeigern im Programm macht das Programm weniger lesbar; die Referenz selbst ist ein Alias ​​der Zielvariablen, und die Operation an der Referenz ist die Operation an der Zielvariablen. Darüber hinaus gibt es den oben erwähnten Unterschied zwischen der Übergabe von Ref und Zeiger an Funktionen.

22 Was ist der Unterschied zwischen Assoziation, Aggregation (Aggregation) und Zusammensetzung (Komposition). )?

Beinhaltet einige Konzepte in UML: Assoziation stellt eine allgemeine Verbindung zwischen zwei Klassen dar, z. B. „Schüler“ und „Lehrer“ ist eine Assoziationsbeziehung Die Beziehung ist eine relativ lockere Beziehung. Die Aggregatklasse muss nicht für die Aggregatklasse verantwortlich sein. Wie in der folgenden Abbildung gezeigt, wird eine leere Raute verwendet, um die Aggregationsbeziehung darzustellen:

Aus Implementierungssicht. Aggregation Kann ausgedrückt werden als:

Klasse A {...} Klasse B { A* a .....

Und die Kombination stellt die Beziehung von enthält-a und dar Die Korrelation ist stärker als die Aggregation: Die Kombinationsklasse und die Kombinationsklasse haben denselben Lebenszyklus. Die Kombinationsbeziehung wird durch eine durchgezogene Raute dargestellt:

Die Implementierungsform ist:

Klasse A{ ...} Klasse B{ A ...}

23 Drei grundlegende Eigenschaften von Objekten orientieren und diese kurz beschreiben?

1. Kapselung: Abstrakte objektive Dinge in Klassen, und jede Klasse implementiert Schutz (privat, geschützt, öffentlich) für ihre eigenen Daten und Methoden

2 . Vererbung: Es gibt drei Implementierungsformen der verallgemeinerten Vererbung: Implementierungsvererbung (bezieht sich auf die Fähigkeit, die Eigenschaften und Methoden der Basisklasse ohne zusätzliche Codierung zu verwenden), visuelle Vererbung (das untergeordnete Formular verwendet das Erscheinungsbild und den Implementierungscode des übergeordneten Formulars). ) und Schnittstellenvererbung (nur Eigenschaften und Methoden werden verwendet, die Implementierung hinkt der Unterklassenimplementierung hinterher). Die ersten beiden (Klassenvererbung) und die letztere (Objektkombination => Schnittstellenvererbung und reine virtuelle Funktion) stellen zwei Möglichkeiten der Wiederverwendung von Funktionen dar.

3. Polymorphismus: Hierbei handelt es sich um eine Technik, bei der ein übergeordnetes Objekt einem oder mehreren seiner untergeordneten Objekte gleichgesetzt wird. Nach der Zuweisung kann das übergeordnete Objekt je nach den Eigenschaften der aktuellen untergeordneten Objekte unterschiedlich konfiguriert werden Art und Weise zu bedienen. Einfach ausgedrückt ist es ein Satz: Es ist erlaubt, einen Zeiger eines Unterklassentyps einem Zeiger eines übergeordneten Klassentyps zuzuweisen.

24 Welche Rolle spielt Polymorphismus?

Es gibt zwei Hauptgründe: 1. Ausblenden von Implementierungsdetails, damit der Code modularisiert werden kann; 2. Schnittstellenwiederverwendung: für Klassen zu Verwenden Sie Vererbung und stellen Sie beim Ableiten den korrekten Aufruf sicher, wenn Sie ein Attribut einer Instanz einer beliebigen Klasse in der Familie verwenden.

25 Warum müssen Sie eine Funktion aufrufen, die von einem C-Compiler in C++ kompiliert wurde? Programm? Externe „C“-Anweisung hinzufügen?

///extern ist ein Schlüsselwort in der Sprache C/C++, das den Umfang von Funktionen und globalen Variablen angibt. Dieses Schlüsselwort teilt dem Compiler mit, dass die von ihm deklarierten Funktionen und Variablen in diesem Modul oder anderen Modulen verwendet werden können

// extern „C ist eine Verbindungsdeklaration. Beim Kompilieren teilt es dem Compiler mit, dass der folgende Code im C-Stil kompiliert und verbunden werden soll. Der Zweck besteht darin, eine gemischte Programmierung von C++, C und anderen Sprachen zu realisieren.

26 Was ist der Unterschied zwischen „Referenz“ und Zeiger? Nachdem ein Zeiger über eine Zeigervariable auf ein Objekt zeigt, wirkt er indirekt auf die Variable, auf die er zeigt. Die Verwendung von Zeigern im Programm macht das Programm weniger lesbar Die Referenz selbst ist die Zielvariable, die Operation an der Referenz ist die Operation an der Zielvariablen. Außerdem ist es der Unterschied zwischen der Übergabe von Referenz und Zeiger an die oben erwähnte Funktion Neues Löschen und Malloc frei?

Antwort: Beide führen dynamische Speicheroperationen auf dem Heap aus. Die Malloc-Funktion muss die Anzahl der Bytes des Speichers angeben Zuweisung und kann das Objekt nicht initialisieren. Löschen ruft den Destruktor des Objekts auf, während Free den Destruktor des Objekts nicht aufruft.24

Merkmale überladener Memberfunktionen:

(1) Gleicher Umfang (In derselben Klasse); ) Der Funktionsname ist derselbe; (3) Die Parameter sind unterschiedlich; (4) Das virtuelle Schlüsselwort ist optional Überschreiben bedeutet, dass abgeleitete Klassenfunktionen Basisklassenfunktionen abdecken:

(1) Unterschiedliche Bereiche (befindet sich in abgeleiteten Klassen bzw. Basisklassen); 🎜> (2) Die Funktionsnamen sind gleich;
(3) Die Parameter sind gleich;
(4) Die Basisklassenfunktion muss das virtuelle Schlüsselwort

26Wenn Sie VC zum Entwickeln eines Programms verwenden, gibt es mehrere häufige Fehler, C2001, c2005, c2011, was sind die Ursachen dafür? Diese Fehler?
Während des Lernprozesses von VC++ sind die Fehlermeldungen der aufgetretenen LNK2001-Fehler hauptsächlich:

ungelöstes externes Symbol „Symbol“ (undefiniertes externes Symbol). „Symbol“).

Diese Fehlermeldung wird generiert, wenn der Linker die referenzierte Funktion, Variable oder Bezeichnung nicht in allen Bibliotheken und Objektdateien finden kann.

Generell gibt es zwei Gründe für Fehler: Erstens existiert die referenzierte Funktion oder Variable nicht, ist falsch geschrieben oder wird falsch verwendet Zweitens eine andere Version der Verbindung kann in der Bibliothek genutzt werden. Bei der Programmierung stoßen wir häufig auf LNK2005-Fehler – wiederholte Definitionsfehler. Tatsächlich sind LNK2005-Fehler nicht schwer zu beheben 27

Stellen Sie STL vor und erklären Sie im Detail, wie STL den Vektor implementiert.

STL (Standard Template Library) besteht aus Container-Algorithmus-Iteratoren.

STL bietet die folgenden Vorteile:

Es kann problemlos eine Reihe von Algorithmen implementieren, z. B. das Suchen nach Daten oder das Sortieren von Daten.

Das Debuggen von Programmen ist sicherer und bequemer ; Sie können sogar den Code, der von Leuten geschrieben wurde, die STL unter der UNIX-Plattform verwenden, leicht verstehen (da STL plattformübergreifend ist). Vector ist im Wesentlichen ein dynamisches Array, das den Array-Speicherplatz entsprechend der Datenzunahme dynamisch vergrößert. 28

Vorlagen und Container vorstellen. Wie erreicht man es? (Vielleicht gebe ich Ihnen ein Beispiel, um es sofort umzusetzen)

Man kann sagen, dass Vorlagen relativ alt sind, aber die aktuelle generische Programmierung ist im Wesentlichen eine Vorlagenprogrammierung.

Es verkörpert eine universelle und verallgemeinerte Idee.

STL hat 7 Hauptcontainer: Vektor, Liste, Deque, Karte, Multimap, Set, Multiset.

29 : Beschreiben Sie kurz das Prinzip der polymorphen Implementierung

Erzeugen Sie eine virtuelle Funktionstabellevtable für diese Klasse. Jeder Eintrag in der virtuellen Funktionstabelle ist ein Zeiger auf die entsprechende virtuelle Funktion. Der Compiler fügt außerdem implizit einen Zeiger vptr in diese Klasse ein (für den vc-Compiler fügt er ihn in die Klasse ein), auf den er zeigt die virtuelle Funktionstabelle. Beim Aufrufen des Konstruktors dieser Klasse führt der Compiler implizit die Zuordnung zwischen vptr und vtable Code, Punkt vptr mit der entsprechenden vtable und verbinden Sie die Klasse mit der vtable dieser Klasse. Kontakt aufgenommen. Wenn außerdem der Konstruktor der Klasse aufgerufen wird, wird der Zeiger auf die Basisklasse nun zum diesem-Zeiger auf die spezifische Klasse und verlässt sich somit auf diesen dieser Zeiger kann die richtige vtable abrufen. Nur so können wir uns wirklich mit dem Funktionskörper verbinden. Dies ist dynamische Bindung und das Grundprinzip der Realisierung von Polymorphismus.

30: Sprechen Sie über Ihr Verständnis von objektorientierter

Analyse:

Objektorientiert kann so verstanden werden, dass jedes Problem behandelt wird, indem zunächst festgestellt wird, dass das Problem aus mehreren Teilen besteht und jeder Teil tatsächlich ein Objekt ist. Entwerfen Sie diese Objekte dann separat und erhalten Sie schließlich das gesamte Programm. Traditionelle Programmierung wird meist auf der Grundlage funktionaler Ideen betrachtet und entworfen, während objektorientierte Programmierung Probleme basierend auf der Objektperspektive betrachtet. Dadurch kann das Programm prägnanter und klarer gestaltet werden.

Erklärung: Das am meisten exponierte in der Programmierung

"Objektorientierte Programmiertechnologie" ist einfach Es ist ein integraler Bestandteil der objektorientierten Technologie. Die Nutzung der objektorientierten Technologie ist ein umfassendes technisches Problem, das nicht nur objektorientierte Analyse-, Design- und Programmiertechnologie erfordert, sondern auch die Hilfe der erforderlichen Modellierungs- und Entwicklungstools erfordert.

31 Warum Vorlagenklassen in C++ verwenden. Analyse:

1) Kann verwendet werden, um dynamisch wachsende und abnehmende Datenstrukturen zu erstellen

2) Es ist typunabhängig, Daher weist es eine hohe Wiederverwendbarkeit auf.

3) Es prüft den Datentyp zur Kompilierungszeit statt zur Laufzeit und gewährleistet so die Typsicherheit

4) Es ist plattformunabhängig und portierbar

5) Es kann einfach verwendet werden Datentypen

32 Was ist der Unterschied zwischen Funktionsvorlagen und Klassenvorlagen?

Antwort: Die Instanziierung von Funktionsvorlagen wird vom Compiler bei der Verarbeitung von Funktionsaufrufen automatisch abgeschlossen, während die Instanziierung von Klassenvorlagen

muss vom Programmierer explizit im Programm angegeben werden.

33. Was sind die wichtigsten Schritte, um eine Winsock-Verbindung herzustellen? (Sehr wichtig, muss gefragt werden) Antwort: Serverseitig:

socker()Einen Socket erstellen, binden (bind) und abhören (zuhören), verwenden Sie akzeptieren()

Warten auf Client-Verbindung.

Client: socker()Socket herstellen, Server verbinden (verbinden ), Verwenden Sie nach dem Verbinden send() und recv (

), schreiben Sie und Daten auf dem Socket lesen, bis der Datenaustausch abgeschlossen ist, closesocket() den Socket schließen.

Serverseite: accept() findet eine Client-Verbindung, richtet einen neuen Socket ein und beginnt erneut auf die Verbindung zu warten

Akzeptieren. Der neu generierte Socket verwendet send() und recv(), um Daten zu schreiben und zu lesen, bis der Datenaustausch abgeschlossen ist, closesock

et()Schließe den Socket.

34 Der Unterschied zwischen Prozessen und Threads.

Antwort: Ein Thread bezieht sich auf eine Ausführungseinheit innerhalb eines Prozesses und ist auch eine planbare Einheit innerhalb eines Prozesses:

( 1) Planung: Threads sind die Grundeinheit der Planung und Zuweisung, und Prozesse sind die Grundeinheiten des Ressourceneigentums

(2) Parallelität: Nicht nur Prozesse können gleichzeitig ausgeführt werden, sondern auch mehrere Threads desselben Prozesses auch gleichzeitig ausgeführt werden.

(3) Eigene Ressourcen: Ein Prozess ist eine unabhängige Einheit, die keine Systemressourcen besitzt, aber auf Ressourcen zugreifen kann, die zum Prozess gehören (4) System-Overhead: Beim Erstellen oder Abbrechen eines Prozesses ist der System-Overhead erheblich größer als der Overhead beim Erstellen oder Abbrechen von Threads, da das System dafür Ressourcen zuweisen und zurückfordern muss.

35. Ist der C++-Typ sicher?

Antwort: Nein. Es können zwei Zeiger unterschiedlichen Typs umgewandelt werden (mithilfe von

reinterpret cast). C# ist typsicher.

  1. Wenn Sie VC zum Entwickeln von Programmen verwenden, gibt es mehrere häufige Fehler: C2001, c2005, c2011. Was sind die Gründe dafür? Fehler.

37 Der Unterschied zwischen Makros und Inline-Funktionen Analyse: Sowohl Inline-Funktionen als auch Makros werden dort erweitert, wo das Programm erscheint. Inline-Funktionen werden nicht durch Funktionsaufrufe implementiert, sondern werden bei dem Programm erweitert, das die Funktion aufruft (wird auch während der Kompilierung abgeschlossen). 🎜>Der Unterschied besteht darin, dass Inline-Funktionen Kompilierungsfunktionen wie die Typerkennung und die Richtigkeit von Anweisungen während der Kompilierung nicht ausführen können und die Makroerweiterungszeit sich von der von Inline-Funktionen unterscheidet (Erweitern während der Laufzeit). 🎜>

38 Wo ist der Einstiegspunkt des Nachrichtenschleifen-Windows-Programms in Win32? Schreiben Sie den Prozess des Windows-Nachrichtenmechanismus

Analyse: Der Einstiegspunkt des Windows-Programms ist die Funktion WinMain(). Windows-Anwendungsnachrichtenverarbeitungsmechanismus:

A. Das Betriebssystem empfängt die Fensternachricht der Anwendung und übermittelt die Nachricht an die Nachrichtenwarteschlange der Anwendung.

B ruft die GetMessage-Funktion in der Nachrichtenschleife auf, um Nachrichten einzeln aus der Nachrichtenwarteschlange abzurufen. Nach dem Abrufen der Nachrichten kann die Anwendung eine Vorverarbeitung der Nachrichten durchführen.

C. Die Anwendung ruft DispatchMessage auf, um die Nachricht an das Betriebssystem zurückzusenden.

D. Das System verwendet den Zeiger auf die Fensterprozedurfunktion, die im Mitglied lpfnWndProc der WNDCLASS-Struktur gespeichert ist, um die Fensterprozedur zum Verarbeiten der Nachricht aufzurufen.

39: Sprechen Sie über Ihr Verständnis oder Wissen über Programmierspezifikationen

Programmierspezifikationen können wie folgt zusammengefasst werden: Programmdurchführbarkeit , Lesbarkeit, Portabilität und Testbarkeit.

Hinweis: Dies ist der allgemeine Überblick über die Programmierspezifikationen. Interviewer müssen die in diesen Beispielen dargestellten Probleme verstehen und darüber nachdenken, wie sie die Fragen der Durchführbarkeit und Portabilität lösen können und Testbarkeit werden mit den obigen Beispielen und Ihren üblichen Programmiergewohnheiten kombiniert, um diese Frage zu beantworten.

40 Warum geben Stream-Operator-Überladungen Referenzen zurück?eaa19fb6b780d8ea2949718feaf11a88"D. Ternärer Operator "? :"Analyse: Es gibt keinen Grund, auch ABD wird nicht funktionieren

2.

In der folgenden Beschreibung von C++-Klassen ist die falsche

A. In der C++-Sprache eingeführte Klassen erfüllen hauptsächlich zwei Funktionen: Datenkapselungsmechanismus und Typdefinition Mechanismus

B. Die in einer C++-Klasse definierten Daten und Funktionen werden als Datenmitglieder bzw. Mitgliedsfunktionen bezeichnet

Als Datenkapselungsmechanismus organisiert die C.C++-Klasse Daten und Operationen an den Daten, um das Ausblenden von Informationen zu erreichen.

Die Mitglieder in der D.C++-Klasse können in vier Typen unterteilt werden: öffentliche Mitglieder, Protect Mitglieder, Privatmitglieder und Freunde

Richtige Antwort: D

3 Unter der Annahme int x = 123 kann die Anweisung eine Ausgabe in der Form „+123“ erzeugen („“ steht für ein Leerzeichen).

A.cout 76cafefbb54709b00c6a632f03df1bde class Sample {…};

B.template1bbcbf404aff658cf5eed197e6af2bc7 class Sample {…} ; C.template8c49dd555a9806de561d35e83b4ae27d class Sample {…}; D.template17441c4bf03cd3139b4c9059754f3614 Sample {…};

Richtige Antwort: C

5

Nicht-C++-integrierte Typen A und B, in welchen Situationen kann B implizit in A konvertiert werden? ? [C++ Medium]a Klasse B : public A { ……}b Klasse B { Operator A( ); ( const B& ); }d. A& Operator= ( const A& ); Analyse: Das erste Element, B, wird öffentlich von A geerbt und kann indirekt geerbt werden. Das zweite Element: B implementiert die implizite Konvertierung in A Das dritte Element: A implementiert den nicht expliziten Parameter B (kann andere Parameter mit Standardwerten haben) Konstruktor Vier Elemente: Zuweisungsoperation, obwohl es ist keine authentische implizite Typkonvertierung, sie kann dennoch als eine angesehen werden


6


The falsche Aussage zu diesem Zeiger ist (A)

Dieser Zeiger muss das anzeigen Beschreibung

    1. Wenn ein Objekt erstellt wird, zeigt dieser Zeiger auf das Objekt
    2. Member-Funktion hat diesen Zeiger Besitzt diesen Zeiger
    3. 7.
    4. In der Deklaration des Funktionsprototyps unten deklariert (B) Spaß als rein virtuelle Funktion

    5. A . void fun()=0; 🎜>
    6. B virtual void fun()=0; >
Friend-Operator obj>obj2 wird vom C++-Compiler als (A) interpretiert.

Operator>(obj1,obj2)

>(obj1,obj2)

obj2. Operator>(obj1)

obj1.oprator>(obj2)

9.假定AB为一个类,则执行“AB a(4),b[3],*p[2];”语句时,自动调用该类构造函数的次数为:B

A) 3  B) 4  C) 6   D) 9

10.假定要对类AB定义加号操作符重载成员函数,实现两个AB类对象的加法,并返回相加结果,则该成员函数的声明语句为:B

A) AB operator+(AB &a,AB &b)

B) AB operator+(AB &a)

C) operator+(AB a)             

D) AB & operator+()

11.有二维字符数组char s[4][6]={"zhang","gao","tang","wang"};执行程序coutdaeeae8786145a0c6601e10ab13634c6打印结果是多少

 using namespace std;
   class A1{
   public:
    int a;
    static int b;
    A1();
    ~A1();
   };
   int main()   {
    cout << sizeof(A1) <<endl;
   }

         解析:是4, 静态变量是存放在全局数据区的, 而sizeof是计算局部栈中分配的大小。

13.死锁的处理

  解析:鸵鸟策略、预防策略、避免策略、检测与解除死锁,只要知道概念就行,不需要掌握

14. 非C++内建型别 A 和 B,在哪几种情况下B能隐式转化为A?[C++中等]

解析:a. class B : public A { ……} // B公有继承自A,可以是间接继承的

     b. class B { operator A( ); } // B实现了隐式转化为A的转化

    c. class A { A( const B& ); } // A实现non-explicit的参数为B(可有其他带默认值的参数)构造函数

    d. A& operator= ( const A& ); // 赋值操作,虽不是正宗的隐式类型转换,但也可以勉强算一个

15以下代码有什么问题?[STL易]

typedef vector IntArray;

IntArray array;

array.push_back( 1 );

array.push_back( 2 );

array.push_back( 2 );

array.push_back( 3 );

// 删除array数组中所有的2

for( IntArray::iterator itor=array.begin(); itor!=array.end(); ++itor )

{

    if( 2 == *itor ) array.erase( itor );

}

    解析:其实里面隐藏着一个很严重的错误:当veci.erase(iter)之后,iter就变成了一个野指针,对一个野指针进行 iter++ 是肯定会出错的。

16 下列代码的输出值是多少?

class A{};

class A1{};

class B : public A{};

class C : public A, public A1{};

class D : public virtual A{};

cout << sizeof ( A ) << endl;

cout << sizeof ( B ) << endl;

cout << sizeof (C) << , 1, 1, 4 erklären: Der von der leeren Klasse belegte Raum ist 1, der leere Klassenraum der Einzelvererbung ist ebenfalls 1 und der leere Klassenraum der Mehrfachvererbung ist immer noch 1, aber die virtuelle Vererbung umfasst virtuelle Tabellen (virtuelle Zeiger). ), also ist die Größe 4.

Verwandte Artikel:

125 grundlegende C#-Interviewfragen und -antworten teilen

Interviewfrage eins, Interviewfrage

Das obige ist der detaillierte Inhalt vonAusgewählte C++-Interviewfragen, die Sie verstehen müssen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn