проблема взаимозависимых классов в одном пространстве имен

#c #visual-c #gcc #forward-declaration #circular-dependency

#c #visual-c #gcc #пересылка-объявление #циклическая зависимость

Вопрос:

Я в реальной ситуации… Мне нужно перенести код, который содержит много взаимозависимых классов и использует пространства имен, чтобы избежать включения. Это работает в MSVC, но я не могу найти способ справиться с этой ситуацией в GCC : (

Содержимое файла myString.h:

 #include "baseBuffer.h"
//I can't forward declare a base class, so I have to include its header

namespace test
{
    class MY_ALLOCATOR
    {
        static const unsigned int LIMIT = 4096;
        class myBuffer : public BaseBuffer<LIMIT>
        {
//...
        }
    };

    template <class T, typename ALLOC = MY_ALLOCATOR> class myContainer
    {
//...
    }

    typedef myContainer<char> myString;
}
  

Содержимое файла baseBuffer.h:

 #include "myObject.h"
//#include "myString.h"
//I can't include **myString.h**, because it includes this header file and I can't seem to find a way to use forward declaration of **myString** class...

namespace test
{
    template <uint limit> class BaseBuffer : public MyObject
    {
        public:
            myString sData;
//...
    }
}
  

Пожалуйста, помогите!

Комментарии:

1. Вам просто нужно разобраться с этим. myString (он же MyContainer) не может разумно использовать базовый буфер для выделения своего пространства, если он использует myString в качестве базы для хранения.

2. Как вы «используете пространства имен, чтобы избежать включения»?

3. И почему вы хотите их избежать? Они необходимы для отдельной модели компиляции C .

4. Все это хорошие вопросы, но проблема в том, что это не мой код…

5. можете ли вы опубликовать небольшое, но поддающееся компиляции подмножество ваших файлов, которые демонстрируют эту проблему (компилируется в MSVC, но прерывается в GCC)?

Ответ №1:

В ваших файлах заголовков отсутствуют защитные элементы.

MSVC, скорее всего, позволяет вам сделать это с помощью расширения. Следовательно, есть два способа решить эту проблему:
1. первое решение — объединить эти два заголовка.
2. вторым решением является прямое объявление шаблонного класса MyContainer и его динамическое создание в basebuffer.hpp (вместо myString sData create myString *sData )

РЕДАКТИРОВАТЬ Добавьте cpp-файл для базового буфера и включите его вместо файла заголовка. В заголовке forward объявите шаблонный класс myString, а в исходный код вы можете включить все, что вам нравится.

Комментарии:

1. MSVC поддерживает #pragma once , что, вероятно, является обычным способом сделать это. Тем не менее, я также не вижу этих инструкций в его коде…

2. Спасибо, но вы уверены, что нет других вариантов?

3. Коди, #pragma once в этом случае не поможет из-за циклической зависимости. И не обращайте внимания на охрану, я думаю, мне не следовало их опускать…

4. @Ryan Прямое объявление — это стандартный способ избежать циклических зависимостей.

5. Хорошо, похоже, мне придется использовать первое упомянутое вами решение.