76 Stimmen

Sollte C++ Header-Dateien eliminieren?

Viele Sprachen wie Java, C# trennen Deklaration und Implementierung nicht. C# hat ein Konzept der teilweisen Klasse, aber Implementierung und Deklaration bleiben dennoch in der gleichen Datei.

Warum hat C++ nicht das gleiche Modell? Ist es praktischer, Kopfdateien zu haben?

Ich beziehe mich auf aktuelle und kommende Versionen des C++-Standards.

14 Stimmen

Ich glaube, es gibt keinen wirklichen Grund für Headerdateien in C++. Alle darin gespeicherten Informationen sind im .cpp dupliziert und können automatisch extrahiert werden (wie von www.lazycplusplus.com demonstriert - Haftungsausschluss: nicht verwendet). Das Problem ist die Kompilierungsgeschwindigkeit und C#&Java haben gezeigt, dass dies überwindbar ist.

0 Stimmen

Wie kann www.lazycplusplus.com alle Informationen erhalten? Was ist, wenn ich einen void-Pointer in der Header-Datei für zukünftige Verwendung deklarieren und reservieren wollte? Es wird nie in der cpp-Datei verwendet oder referenziert.

1 Stimmen

THanks.... Ich habe auch keine Ahnung, warum es abgelehnt wurde.

1voto

Dimitri C. Punkte 21080

Ein Vorteil dieser Trennung ist, dass es einfach ist, nur die Oberfläche anzusehen, ohne einen fortgeschrittenen Editor zu benötigen.

1voto

polyglot Punkte 1973

Es steckt Wert darin, die Klassenschnittstelle in einer separaten Komponente zur Implementierungsdatei zu definieren.

Es kann mit Interfaces gemacht werden, aber wenn du diesen Weg gehst, dann sagst du implizit, dass Klassen in Bezug auf die Trennung von Implementierung und Vertrag unzureichend sind.

Modula 2 hatte die richtige Idee, Definierungs- und Implementierungsmodule. http://www.modula2.org/reference/modules.php

Die Antwort von Java/C# ist eine implizite Implementierung derselben (allerdings objektorientiert).

Header-Dateien sind ein Notbehelf, weil sie Implementierungsdetails ausdrücken (wie private Variablen).

Bei meinem Wechsel zu Java und C# finde ich, dass, wenn eine Sprache IDE-Unterstützung für die Entwicklung erfordert (so dass öffentliche Klassenschnittstellen in Klassenbrowsern navigierbar sind), dann ist das vielleicht ein Hinweis darauf, dass der Code nicht aus eigener Kraft besonders lesbar ist.

Ich finde die Mischung aus Schnittstelle und Implementierungsdetails ziemlich furchtbar.

Entscheidend ist, dass die Unfähigkeit, die öffentliche Klassensignatur in einer prägnanten, gut kommentierten Datei unabhhängig von der Implementierung zu dokumentieren, für mich darauf hindeutet, dass das Design der Sprache für die Bequemlichkeit der Autorenschaft geschrieben ist, nicht aber für die Bequemlichkeit der Wartung. Nun schwärme ich von Java und C#.

1voto

David Thornley Punkte 55244

Wenn Sie den Grund dafür wissen möchten, warum das niemals passieren wird: Es würde so ziemlich alle vorhandene C++-Software zerstören. Wenn Sie sich einige der Entwurfsdokumente des C++-Komitees ansehen, haben sie verschiedene Alternativen untersucht, um zu sehen, wie viel Code dadurch zerstört würde.

Es wäre viel einfacher, die switch-Anweisung in etwas halbwegs Intelligentes zu ändern. Das würde nur wenig Code zerstören. Es wird dennoch nicht passieren.

ÜBERARBEITET FÜR NEUE IDEE:

Der Unterschied zwischen C++ und Java, der C++-Headerdateien erforderlich macht, besteht darin, dass C++-Objekte nicht unbedingt Zeiger sind. In Java werden alle Klasseninstanzen zwar durch Zeiger referenziert, obwohl es nicht so aussieht. C++ hat Objekte, die im Heap und im Stack allokiert sind. Das bedeutet, dass C++ eine Möglichkeit benötigt, um herauszufinden, wie groß ein Objekt sein wird und wo sich die Datenelemente im Speicher befinden.

0 Stimmen

C++ benötigt eine Möglichkeit, das Klassenlayout im Speicher zu kennen, bedeutet nicht unbedingt, dass es Headerdateien benötigt. Headerdateien sind derzeit der Mechanismus, mit dem C++ diese Informationen erhält, nicht der einzige mögliche Mechanismus.

0voto

coppro Punkte 14158

Keine Sprache existiert ohne Kopfdateien. Es ist ein Mythos.

Schauen Sie sich eine proprietäre Bibliotheksverteilung für Java an (Ich habe keine Erfahrung mit C#, aber ich würde erwarten, dass es das Gleiche ist). Sie geben Ihnen nicht die vollständige Quelldatei; sie geben Ihnen einfach eine Datei, in der die Implementierung jedes Methode leer ist ({} oder {return null;} oder ähnliches) und alles, was sie verstecken können, versteckt ist. Das kann man nur als Kopfdatei bezeichnen.

Es gibt jedoch keinen technischen Grund, warum ein C- oder C++-Compiler alles in einer entsprechend markierten Datei als extern zählen könnte, es sei denn, diese Datei wird direkt kompiliert. Die Kosten für die Kompilierung wären jedoch immens, da weder C noch C++ schnell zu parsen sind, und das ist ein sehr wichtiger Aspekt. Jede komplexere Methode, Kopfdateien und Quellcode zu verschmelzen, würde schnell auf technische Probleme stoßen, wie die Notwendigkeit für den Compiler, das Layout eines Objekts zu kennen.

0 Stimmen

Der Java-Compiler entnimmt diese Informationen aus den .class-Dateien. Nicht nur das: Das Sun JDK wurde mit dem Quellcode für die meisten Klassen geliefert (außer denen in com.sun.*).

0 Stimmen

@andref stimme zu, die meisten modernen Sprachen (die normalerweise dynamische Sprachen sind) kommen nicht mit einer formellen Header-Datei.

-1voto

Vincent Punkte 2642

Oh Yes!

Nachdem ich in Java und C# programmiert habe, ist es wirklich ärgerlich, für jede Klasse zwei Dateien zu haben. Also habe ich mir überlegt, wie ich sie zusammenführen kann, ohne den vorhandenen Code zu brechen.

Tatsächlich ist es sehr einfach. Setzen Sie einfach die Definition (Implementierung) in einen #ifdef-Bereich und fügen Sie beim Kompilieren dieser Datei der Compiler-Befehlszeile ein define hinzu. Das war's.

Hier ist ein Beispiel:

/* Datei ClassA.cpp */

#ifndef _ClassA_
#define _ClassA_

#include "ClassB.cpp"
#include "InterfaceC.cpp"

class ClassA : public InterfaceC
{
public:
    ClassA(void);
    virtual ~ClassA(void);

    virtual void methodC();

private:
    ClassB b;
};

#endif

#ifdef compiling_ClassA

ClassA::ClassA(void)
{
}

ClassA::~ClassA(void)
{
}

void ClassA::methodC()
{
}

#endif

Führen Sie beim Kompilieren dieser Datei den folgenden Befehl aus:

-D compiling_ClassA

Die anderen Dateien, die ClassA einbeziehen müssen, können einfach folgendes tun:

#include "ClassA.cpp"

Natürlich kann die Hinzufügung des Defines in der Befehlszeile leicht mit einer Makroerweiterung (Visual Studio Compiler) oder mit automatischen Variablen (GNU Make) hinzugefügt werden, wobei die gleiche Benennung für den Define-Namen verwendet wird.

2 Stimmen

Dies verfehlt den Sinn der Trennung zwischen Kopf- und Quelldatei völlig (na ja, fast). Wenn Sie dies tun, werden Änderungen an der Implementierung von ClassA dazu führen, dass alle Benutzer von ClassA.cpp neu kompiliert werden müssen (es sei denn, Ihr Build-System ist wirklich intelligent, was an sich schon Kosten verursacht).

0 Stimmen

@Mankarse bei der Verwendung von Schnittstellen zwischen Klassen (wie in Java oder C#) hat die Änderung der Implementierung einer Klasse nur geringe Auswirkungen auf die Kompilationsabhängigkeit.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X