#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. Хорошо, похоже, мне придется использовать первое упомянутое вами решение.