2016-11-02 10 views
0

Es ist eine ziemlich grundlegende Frage, aber ich habe Namespaces eigentlich nie selbst definiert. Ich versuche, die Klassen in meiner Qt-basierten Bibliothek in verschiedenen Namespaces zu gruppieren (und erlaubt auch eine einfachere Erweiterung ohne Namenskonflikte). Zum Beispiel der Hauptklasse (das auch die Bibliothek darstellt) gehört zu dem Top-Level-Namespace lib:C++ - Namespaces - Forward-Deklaration und Sichtbarkeit verschachtelter Namespaces

namespace lib { 
    class LibClass; 
} 

Diese LibClass verwendet eine Reihe von anderen Namespaces und Klassen, die in anderen Header-Dateien definiert sind, die in dem enthalten sind Header LibClass:

#include <QObject> 
#include "libclass_global.h" 
#include "Manager.h" 
#include "Configurator.h" 

namespace lib { 
    class LibClass; 
} 

class LIBCLASSSHARED_EXPORT LibClass : public QObject { 
    public: 
     LibClass(); 
     ... 
    signals: 
     ... 
    private slots: 
     ... 
    public slots: 
     ... 
    private: 
     lib::core::communication::Manager manager;    // PROBLEM HERE 
     lib::core::communication::Configurator configurator; // PROBLEM HERE 
} 

mit Manager.h

enthält
namespace lib { 
    namespace core { 
     namespace communication { 
      class Manager; 
     } 
    } 
} 

class Manager { 
    public: 
     Manager(); 
     ... 
    private: 
     ... 
} 

und Configurator.h

namespace lib { 
    namespace core { 
     namespace communication { 
      class Configurator; 
     } 
    } 
} 

class Configurator { 
    public: 
     Configurator(); 
     ... 
    private: 
     ... 
} 

Die Inhalte der Klassen enthalten, sind hier nicht wichtig.

Nach der Kompilierung bekomme ich, dass core in Namespace q3dtp keinen Namen nennen. Also im Grunde von dem, was ich verstehe, ich brauche Erklärung im Header meiner LibClass zu verwenden, nach vorne, da Namespace scheinen nicht wirklich mit dem Einsetzen der Header-Dateien enthalten sein, dass diejenigen (aus irgendeinem Grund) enthalten:

namespace lib { 
    class LibClass; 

    namespace core { 
     namespace communication { 
      class Manager; 
      class Configurator; 
     } 
    } 
} 

Die Problem damit ist, dass ich jetzt nur auf Zeiger beschränkt bin, da ich Manager und Configurator vorwärts-deklariere. Ich möchte es vermeiden, Dinge dynamisch zuzuweisen, wann immer es möglich ist (und nicht benötigt wird).

Also ist die Frage hier, wie löse ich dieses Problem? Ich kann offensichtlich alle meine Klassen-Deklarationen in dieselbe Kopfzeile und ihre Definitionen in dieselbe Quelldatei verschieben. Dies wird jedoch die Aufrechterhaltung der Dinge in Zukunft schwierig machen. Nur das Deklarieren der Sub-Namespaces scheint das Problem auch nicht zu lösen - ich bekomme, dass beide Klassen keinen Typ nennen und dass LibClass keine Member-Namen <name_of_class_from_nested_namespace> hat.

Antwort

5

Ihre Deklaration von LibClass ist falsch. Es sollte sein:

namespace lib { 
    class LibClass; 
} 

class lib::LibClass { 
    ... 
}; 

oder

namespace lib { 
    class LibClass { 
     .... 
    }; 
} 

Wie es derzeit steht, Sie lib::LibClass und definieren ::LibClass (zwei völlig verschiedene Klassen) deklarieren.

Dies gilt auch für alle anderen Klassen.

2

Wenn Sie das tun

namespace ns { 
    class cls; 
}; 

class cls { 
}; 

Sie erklären, nach vorne ein Typ, und dann andere definieren.Sie müssen den Klassennamen qualifizieren:

namespace ns { 
    class cls; 
}; 

class ns::cls { 
}; 

Mit C++ 17 kommen zusammen, wenn dies für verschachtelte Namensräume zu umständlich ist, können Sie folgendes tun:

namespace ns1::ns2::ns3 { 

    class cls { 
    }; 

}