Frage

Ich lerne immer noch C ++, und ich habe noch nie meine eigenen Namensräume geschaffen wirklich. Ich war mit ihnen zu experimentieren und während ich die meisten Dinge zu Arbeit bekam, gibt es eine Sache, die ich kann immer noch nicht zu tun scheinen. Ich möchte eine statische Methode innerhalb einer Klasse aufrufen können, ohne so etwas wie NameOfClass::method eingeben. Hier ist, was ich dachte, sollte der Code aussehen, aber es funktioniert 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, zu tun, was ich ohne die Eingabe einer A::foo tun möchte?

War es hilfreich?

Lösung

Es gibt keinen Weg, um es Sie müssen die Klassennamen für statische Methoden angeben.

using namespace Test;

Dann:

int answerToEverything = A::foo();

Andere Tipps

In C ++, Sie / besonders / haben die Compiler-Fehlermeldungen sorgfältig zu lesen.

Beachten Sie der erste Fehler war „Fehler:‚A‘ist kein Namespace-Namen“. Das ist wahr, A ist ein Klassenname.

using namespace Foo; // brings in  all of foo;
using Bar::Baz // brings in only Baz from Bar

Sie wollen schreiben:

using Test::A;

Das macht zwei gute Dinge: es in A bringt für Sie zu nutzen, und es bringt nicht in der ganzen übrigen Test, der zu gut ist, weil man nur in bringen sollte, was Sie brauchen, um nicht versehentlich hängen von etwas, das Sie nicht erkennen, Sie je nach.

Wie jedoch foo in einem statischen sind, werden Sie noch explizit auf A :: foo beziehen müssen. (Es sei denn, Sie etwas tun, wie eine freie Funktion zu schreiben, die auf A :: foo leitet;. In der Regel ist dies eine schlechte Idee, wenn Sie tun es nur einige Eingabe zu speichern)

Einige können raten, nicht auf alle mit Erklärungen verwenden, anstatt vollständig alle Namen zu qualifizieren.

Das ist aber (Stroustrup zu zitieren) „mühsam und fehleranfällig“, und es wird in der Art von Refactoring: sagen, dass Sie in vollem Umfang jede Verwendung der Klasse foomatic :: Stapel, qualifizieren und dann Verwaltung besteht, kurz bevor Sie‘ re über die Produktion zu gehen, dass Sie barmatic die sehr ähnlich Stack-Klasse verwenden, da barmatic nur Ihre Firma gekauft.

Haben Sie überall voll qualifiziert, dann würden Sie eine Menge Grepping tun, in der Hoffnung Ihre regex waren richtig. Wenn Sie eine using-Deklaration verwendet, können Sie nur ein Update auf Ihre (hoffentlich gemeinsam) Header-Datei machen. Auf diese Weise wird eine using-Deklaration ist ein viel wie ein „typedef int ourInt;“ oder eine offensichtliche Konstante oder const: „const int FOO = 1;“, dass es bietet einen Ort, etwas zu ändern, die an vielen Orten bezeichnet wird. Voll qualifizierenden diese Leistung nimmt einen Namensraum bei jeder Benutzung entfernt.

Im Gegensatz dazu hatte eine using-Direktive verwendet und in allen Namespace foomatic gebracht, Ihre grep noch schwieriger gewesen wäre, wenn das Management auf barmatic :: Foo bestanden sagen, aber sie hatte noch foomatic zu verwenden: Baz, die barmatic Äquivalent für Baz aus irgendeinem Grund unbrauchbar zu sein.

in einer Art So bringt (Klasse, Funktion, konstant) zu einer Zeit, in der Regel der flexibelste, die Art und Weise, um am besten, sie gegen unvermeidlich zu schützen, aber noch unbekannte Änderungen. Wie in den meisten Codierung, möchten Sie eine langweilige Wiederholung zu minimieren, während eine ausreichende Granularität zu halten.

Nein, es ist nicht möglich, zu tun, was Sie versuchen, in irgendeiner Art und Weise elegant zu tun. Das nächste, was Sie in der Lage sein zu tun, sind ein Makro oder eine Inline-Funktion, die Delegierten auf Ihre Funktion zu erstellen. Allerdings sind diese beiden Alternativen eher hässlich, so dass ich keine Codebeispiele gehen zu schreiben. Gerade den sauren Apfel beißen und den vollständigen Namen angeben oder Ihren Code Refactoring, so dass die statischen Methoden sind nur globale Funktionen.

Seien Sie nicht ein „using namespace“ Missbraucher. Verwenden Sie diese Namensräume!

std::cout << Test::A::foo() << std::endl;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top