2016-11-02 2 views
0

Это довольно простой вопрос, но я на самом деле никогда не определял пространства имен самостоятельно. Я пытаюсь сгруппировать классы в моей библиотеке на основе Qt в разных пространствах имен (а также позволяет упростить расширение без конфликтов имен). Например основной класс (который также представляет библиотеку) принадлежит к пространству имен верхнего уровня lib:Пространства имен C++ - декларация вперед и видимость вложенных пространств имен

namespace lib { 
    class LibClass; 
} 

Этот LibClass использует кучу других пространств имен и классов, которые определены в других файлах заголовков, которые включены в заголовок 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 
} 

с Manager.h содержащий

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

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

и Configurator.h содержащий

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

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

содержимое классов не важно.

После компиляции я получаю, что core в пространстве имен q3dtp не называет тип. Так в основном от того, что я понимаю, что нужно использовать вперед декларацию в заголовке моего LibClass поскольку пространство имен, похоже, не на самом деле быть включены вставки файлов заголовков, которые содержат те (по некоторым причинам):

namespace lib { 
    class LibClass; 

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

проблема в том, что теперь я ограничена указателями только с тех пор, как я переадресую объявление Manager и Configurator. Я бы хотел, чтобы избежать динамического распределения материала, когда это было возможно (и не нужно).

Итак, вопрос в том, как решить эту проблему? Очевидно, я могу переместить все объявления классов в один заголовок и их определения в один и тот же исходный файл. Однако в будущем это будет довольно сложно поддерживать. Только объявление областей под-имен, похоже, также не решает проблему: я понимаю, что оба класса не называют тип, а далее LibClass не имеет имен участников <name_of_class_from_nested_namespace>.

ответ

5

Ваше заявление LibClass неверно. Оно должно быть:

namespace lib { 
    class LibClass; 
} 

class lib::LibClass { 
    ... 
}; 

или

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

В настоящее время он стоит, вы объявляете lib::LibClass и определения ::LibClass (две совершенно разные классы).

Это относится ко всем вашим другим классам.

2

Когда вы

namespace ns { 
    class cls; 
}; 

class cls { 
}; 

Вы вперед объявить один тип, а затем определить другой.Вы должны квалифицировать имя класса:

namespace ns { 
    class cls; 
}; 

class ns::cls { 
}; 

В C++ 17, поставляемая вместе, если это становится слишком громоздким для вложенных пространств имен, вы можете сделать следующее:

namespace ns1::ns2::ns3 { 

    class cls { 
    }; 

} 
Смежные вопросы