Форвардная декларация - PullRequest
       10

Форвардная декларация

3 голосов
/ 25 апреля 2011

У меня циклическая избыточность циклическая зависимость между двумя классами в моем проекте, StatusEffect и BaseCharacter.

Оба класса должны знать друг друга как BaseCharacter должен хранить набор StatusEffect с, а StatusEffect должен иметь возможность выполнять операции с BaseCharacter.Я не думаю, что это возможно, чтобы устранить это поведение и по-прежнему работать правильно.Вот что я пытаюсь сделать прямо сейчас:

Базовый символ существует внутри пространства имен Game::Character, а StatusEffect существует внутри пространства имен Game::StatusEffects

внутри StatusEffects.h, я пересылаюобъявил BaseCharacter вот так:

namespace Game {
    namespace Character {
        class BaseCharacter;
    }
}

тогда под ним у меня есть:

namespace Game
{   
    namespace StatusEffects
    {
        class StatusEffect
        {
        public:
            virtual void TickCharacter(Game::Character::BaseCharacter* character, int ticks = 1)
            {
                std::cout << "Name " << character->GetName() << std::endl;
            }
        protected:
        private:
            std::string name;
            int StatusEffectUID;
        };
    }
}

Однако, это дает мне ошибку компилятора:

Ошибка 1 ошибка C2027: использование неопределенного типа 'Game :: Character :: BaseCharacter'

Я подумал, что, поскольку я использую указатель, это прямое объявление в порядке.Есть ли что-то еще, что мне нужно переслать объявить?Мне не нужно заранее объявлять все определение класса, не так ли?

Ответы [ 2 ]

9 голосов
/ 25 апреля 2011

Вы не можете вызвать метод через указатель на объявленный заранее класс.Вы должны переместить этот код куда-нибудь, где класс уже определен - например, в файл .cpp, который включает определение обоих классов.

2 голосов
/ 25 апреля 2011

Ваш форвард declaration в порядке.Однако вы не должны ссылаться ни на одного из членов такого класса.

Вы должны только объявить метод TickCharacter в заголовке.Затем вы должны define метод StatusEffect::TickCharacter в своем собственном файле модуля после #include файла заголовка, который содержит полное объявление BaseCharacter.

...