C++ namespaces zur Vermeidung langer Wege
Ich bin immer noch lernen, C++, und ich habe nie wirklich meine eigene namespaces vor. Ich war mit Ihnen zu Experimentieren, und während ich die meisten Dinge zu arbeiten, es gibt eine Sache, ich kann immer noch nicht scheinen, zu tun. Ich möchte in der Lage sein, zum aufrufen einer statischen Methode in einer Klasse ohne die Eingabe so etwas wie NameOfClass::method
. Hier ist, was ich dachte, der code Aussehen sollte, aber es nicht kompilieren:
Datei A.h
,
namespace Test
{
class A
{
public:
static int foo() { return 42; }
};
}
Datei main.cpp
,
#include <iostream>
#include "A.h"
using namespace std;
using namespace Test::A;
int main()
{
cout << foo() << endl;
return 0;
}
Der compiler gibt mir:
main.cpp:6: error: ‘A’ is not a namespace-name
main.cpp:6: error: expected namespace-name before ‘;’ token
main.cpp: In function ‘int main()’:
main.cpp:10: error: ‘foo’ was not declared in this scope
Ist es möglich, das zu tun, was ich versuche zu tun, ohne die Eingabe A::foo
?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es gibt keine Möglichkeit um ihn herum müssen Sie den Klassennamen für die statische Methoden.
Dann:
In C++, Sie /besonders/gelesen haben, die compiler-Fehlermeldungen gezielt.
Bemerken, der erste Fehler war "Fehler: 'A' ist kein namespace-name". Das ist wahr, a ist Eine classname.
Sie schreiben wollen:
Tut zwei gute Dinge: er bringt in Einer für Sie zu verwenden, und es bringt auch nicht in allen den rest Testen, was auch gut ist, denn solltest du nur mitbringen, was Sie brauchen, so dass Sie nicht versehentlich hängen auf etwas, das Sie nicht erkennen, Sie sind abhängig.
Aber, wie foo statisch Ein, du wirst noch finden A::foo ausdrücklich. (Es sei denn, Sie etwas wie das schreiben einer freien Funktion, nach vorne zu A::foo; im Allgemeinen ist dies eine schlechte Idee, wenn Sie das nur tut, um sich Tipparbeit ersparen.)
Einige vielleicht raten, nicht über Erklärungen, sondern voll qualifizierende alle Namen.
Aber dies ist (Zitat Stroustrup) "mühsam und fehleranfällig", und es wird in der Weise des refactoring: sagen Sie, dass Sie voll zu qualifizieren jeder Klasse FooMatic::Stack, und dann das management besteht darauf, nur bevor man in die Produktion gehen, die Sie verwenden BarMatic ist sehr ähnlich Stack-Klasse, da barMatic gerade gekauft aus Ihrem Unternehmen.
Hatte Sie voll qualifiziert überall, Sie würde tun eine Menge grepping, in der Hoffnung Ihre regex richtig war. Wenn Sie eine using-Deklaration, können Sie einfach machen ein Update für Eure (hoffentlich gemeinsam) header-Datei. Auf diese Weise, ein mit Deklaration ist ein viel wie eine "typedef int ourInt;" oder ein manifest-oder const-Konstante: "const int FOO = 1;" in, dass es bietet einen Ort um etwas zu ändern, die bezeichnet, an vielen Orten. Voll qualifizierten namespace bei jedem Einsatz nimmt, die profitieren.
Umgekehrt, hatte Sie eine using-Direktive und brachte alle Namespace-FooMatic, dein grep könnte noch härter werden, wenn etwa das management Bestand darauf, BarMatic::Foo, aber Sie hatte noch zu verwenden FooMatic:Baz, die BarMatic äquivalent für die Baz wird aus welchem Grund auch immer unbrauchbar.
So dass in einem Typ (Klasse, Funktion, Konstante) in einer Zeit ist in der Regel die flexibelste, den Weg, um am besten schützen Sie sich gegen das unvermeidliche, aber noch unbekannte Veränderungen. Wie in den meisten anderen Codierung, die Sie wollen, zu minimieren mühsame Wiederholung, während eine ausreichende Granularität.
Nein, es ist nicht möglich, das zu tun, was Sie versuchen zu tun, in irgendeiner elegante Mode. Die nächste Sache, die Sie werden in der Lage sein zu tun sind zu schaffen, ein makro oder eine inline Funktion, die Delegierten an Ihre Funktion. Allerdings haben diese beiden alternativen sind ziemlich hässlich, so werde ich nicht zum posten von code-Beispielen. Nur den sauren Apfel beißen und geben Sie den ganzen Namen, oder umgestalten von code, so dass die statischen Methoden sind nur Globale Funktionen.
Nicht ein "using namespace" Täter. Verwenden Sie diesen namespaces!