вперёд объявить производный класс из шаблона c ++ - PullRequest
3 голосов
/ 16 сентября 2011

У меня проблемы с обработкой некоторых изломов в реализации проекта. Это выглядит примерно так:

У меня есть базовый класс шаблона, у которого есть метод преобразования.

// Foo.h

class Bar;

template<typename T>
class Foo {

    virtual const Bar toBar();

}

Я хочу, чтобы производный класс Bar наследовал от определенной формы Foo, например:

// Bar.h
class Bar : public Foo<float> {
    // Insert Bar methods here, Etc.
}

Поскольку Foo является шаблоном, реализация должна быть полностью определена в заголовке, это вызывает проблему, связанную с тем, что реализация метода toBar () должна иметь возможность создавать экземпляр типа Bar. Это говорит о том, что мне нужно включить заголовочный файл Bar.h после определения Foo, но до реализации Foo.

Однако в Bar.h класс Bar является производным от Foo, поэтому необходимо предоставить полное определение Foo. Это вызывает проблемы, поскольку два файла имеют циклическую зависимость, которая не может быть решена с помощью прямых объявлений, поскольку прямое объявление является производным классом.

Это становится еще сложнее, если другой класс SomeClass имеет член данных типа Bar, как это требуется, включая Bar.h, который включает в себя Foo.h, который (потому что это шаблон) включает в себя Bar.h.

Да, и для ясности, все заголовочные файлы имеют защиту включения, используя

#ifndef _HEADER_NAME_H_
#define _HEADER_NAME_H_
...
#endif

Как другие люди решали сложные проблемы, подобные этой?

В качестве более конкретного примера, скажем, у меня есть класс Array, у которого есть метод для преобразования его в читаемый человеком класс String, такой как toString () ... однако класс String объявлен как

class String : public Array<char> {...};

Заранее спасибо. Гэри.

Ответы [ 2 ]

1 голос
/ 16 сентября 2011

Чтобы Foo< float > был базовым классом, он должен быть полностью определен точкой определения Bar. Тем не менее, Foo не обязательно знать о Bar, если вы можете сделать Bar зависимым типом имени в Foo.

Может потребоваться предварительное объявление Bar перед определением Foo. Если вы разместите / свяжете более конкретный код, возможно, я смогу дать вам лучший ответ.

Попробуйте это:

class Bar;

template< typename T, typename DependantBar = Bar >
class Foo {

    virtual const DependantBar toBar();

}
0 голосов
/ 16 сентября 2011
class Bar : public Foo<float> {
    template <typename T>
    Bar create(const Foo<T>&);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...