2012-07-05 6 views
19

Bei der Verwendung verschachtelter Namespaces sind manchmal vollständig qualifizierte Namen ziemlich lang. Ich weiß, dass ich namespace abc = aaa::bbb::ccc verwenden kann, um die Menge des Tippens zu reduzieren (es kann in einigen Fällen auch die Lesbarkeit verbessern).Konsequenter Ansatz zum Umbenennen von Namespaces in C++

Ich bin mir nicht sicher, was jedoch der beste Weg ist, um diese Umbenennung über alle Dateien in einem Projekt zu erreichen. Der direkte Ansatz (d. H. Das Umbenennen langer Namespaces auf Benutzerebene) kann dazu führen, dass verschiedene Kurznamen für den gleichen vollständig qualifizierten Namen in verschiedenen Dateien verwendet werden. Also habe ich mir überlegt, einen konsistenteren Weg zu finden.

Zum Beispiel nehmen wir an, so etwas wie:

project 
    |- client 
    | |- core 
    | |- plugin 
    | |- util 
    |- server 
     ... 

Ich dachte, ein Kopf pro Verzeichnis einschließlich der reduzierten Namen zu erstellen. Zum Beispiel würde project/client/core/core.hnamespace pr_cl_core = project::client::core enthalten (ich weiß, dass das Beispiel für diesen kurzen Namen eher schlecht ist, aber in realen Projekten machen sie mehr Sinn). Dann würde ich core.h in alle Header-Dateien in project/client/core einfügen, so dass, wenn ein Header aus diesem Verzeichnis enthalten ist, sagen wir project/client/plugin/plugin_foo.h, die kurzen Namespace-Versionen sind leicht verfügbar.

Ist das ein guter Ansatz, dies zu tun? Gibt es einen anderen besseren Weg?

Ich habe mehrere Fragen zu C++ - Namespaces auf SO (zum Beispiel 1 und 2) gefunden, aber keiner von ihnen bezieht sich auf wie Projekt Namensumbenennung projektweit zu lösen.

EDIT: Darüber hinaus könnte ein solcher Mechanismus verwendet werden, um lange Namensräume (wie Boosts) für ein ganzes Projekt systematisch umzubenennen. Zum Beispiel umbenennen ich in der Regel einige Namensräume wie:

namespace ip = boost::asio::ip; 
namespace ptime = boost::posix_time; 

Zur Zeit mache ich das auf einer pro-Übersetzung Einheitsbasis, aber ich würde es tun einen globalen Ansatz für das gesamte Projekt mit.

+0

Sie könnten das tun, oder Sie könnten es noch einfacher machen: Haben Sie eine Überschrift in der obersten Ebene, die Prototypen für alle Namespaces und die Aliase deklariert. Dann schließe das einfach in die Unterordner ein. – Linuxios

+0

@Linuxios Ich habe auch so etwas gedacht, aber das führt vielleicht zu vielen Abhängigkeiten: Wenn ich diese globale Datei ändere, müssten praktisch alle Dateien im Projekt neu kompiliert werden. Wenn sich die Struktur von Namespaces nicht zu sehr ändert, sollte das kein großes Problem sein. – betabandido

+0

@betabendido: Ah. Was ist mit der schnellen und schmutzigen Lösung? Präprozessor-Makros! Erklären Sie sie einfach in jeder Datei für ihre Aliase. Auf diese Weise kann jede Datei ihre eigenen Aliase haben. Ja, die Leute werden für die Duplizierung von Code schimpfen, aber Sie könnten immer ein Build-Time-Skript hinzufügen, um es für Sie zu tun ... – Linuxios

Antwort

1

Ich würde argumentieren, wenn Sie wiederholt lange Namespace-Namen eingeben müssen, dann ist etwas in Ihrer Namespace-Hierarchie falsch.

Angenommen, Sie hätten das gleiche mit Klassen, immer wieder selbst tippen obj->sub()->subsub()->some_method() eingeben. Dies wäre eine Verletzung der Law of Demeter. Im Fall von Klassen würden Sie Ihren Code (durch das Schreiben von Wrapper-Funktionen) umgestalten, so dass Klassen in der Hierarchie nur auf eine Ebene mehr auf Methoden zugreifen müssen.

Das gleiche sollte mit Namensräumen durchgeführt werden: Wenn Sie project::client::core anrufen, dann sollten Sie Wrapper-Funktionen/Klassen in client schreiben die notwendigen Schnittstellen zu project belichten. Wenn Sie dies überall tun müssen, warum sollten Sie Ihre Namensraumstruktur nicht so abflachen, dass client und core auf demselben Niveau liegen?

Die Tatsache, dass Boost verschachtelten Namespace verwendet, ist nur teilweise wahr, weil die meisten verschachtelten Namespaces wie aux und detail nicht von Clients aufgerufen werden sollen. Z.B. Boost.MPL ist ein wirklich gutes Beispiel für eine Bibliothek, die sorgfältig darauf achtet, verschachtelte Namespaces nicht freizugeben.

+0

Nehmen wir an, ich entscheide mich, den Namespace zu reduzieren, damit ich dieses Problem los werde. Wie würde ich das Problem der langen Namensräume von Boost lösen? Ich möchte vermeiden, 'boost :: asio :: ip :: tcp :: socket' (oder ähnliches Zeug) zu tippen. – betabandido

+0

@betabandido Boost.Asio hat tatsächlich eine zu lange Namespace-Benennung. Sie können zumindest versuchen, einige davon mit Aliasnamen zu isolieren: 'Namespace asio = boost :: asio;' und in Low-Level-Code, der TCP/IP-Sockets verwendet, könnten Sie 'namespace socket = bost: asio :: ip :: tcp :: socket; 'z – TemplateRex

+0

Das ist eigentlich, was ich gerade mache.Aber meine Frage ist, wie man diese Umbenennung systematisch in alle Quelldateien eines Projekts umsetzt. Zumindest gibt es zwei potentielle Vorteile, dies auf systematische Weise zu tun: 1) weniger Schreibaufwand (insbesondere bei mehreren Umbenennungen) und 2) eine konsistente Umbenennung über das gesamte Projekt hinweg. – betabandido

Verwandte Themen