сообщение об ошибке: Неполный тип в спецификаторе вложенного имени - PullRequest
1 голос
/ 27 апреля 2020

Я знаю, что есть много похожих именованных вопросов, но я не могу понять свою проблему после прочтения их числа.

Я пишу игру для проекта класса.

В class Dungeon, function monsterTurn() необходим доступ к setCurrSp(), который объявлен как защищенный в class Hero. Поэтому я попытался добавить monsterTurn() в качестве функции друга к Hero. Поскольку у меня было #include "Hero.hpp" в class Dungeon, я использовал прямое объявление, но оно выдает ошибку Incomplete type 'Dungeon' named in nested name specifier.

Я знаю, что объявление setCurrSp() как publi c решит все эти проблемы, но я не хочется расставаться с сеттером c. Похоже, что бэкдор открыт для неожиданных изменений. Поправьте меня, если я ошибся в этом.

Ниже приведены часть кодов.

Hero.hpp

#include <stdio.h>
#include <iostream>
#include <sstream>
#include <vector>
#include "Entity.hpp"
class Dungeon;

class Hero : public Entity{

protected:
    void setCurrSp(int currSp)              { this->currSp = currSp;}
public:
    friend void Dungeon::monstersTurn(vector<Hero>::iterator hero, vector<Hero> heros);
}

Dungeon.hpp

#include <stdio.h>
#include <vector>
#include "Hero.hpp"
#include "Monster.hpp"
class Dungeon{
public:
    void monstersTurn(vector<Hero>::iterator hero, vector<Hero> heroes);
}

Любая помощь будет оценена.

1 Ответ

1 голос
/ 27 апреля 2020

Для декларации friend

    friend void Dungeon::monstersTurn(vector<Hero>::iterator hero, vector<Hero> heros);

форвардной декларации

class Dungeon;

недостаточно.

Демонстрация:

class Dungeon; // forward declaration

class Hero {
  friend void Dungeon::takeHero(Hero&);
};

class Dungeon {
  public:
    void take(Hero&);
};

Вывод:

main.cpp:5:38: error: invalid use of incomplete type 'class Dungeon'
    4 |   friend void Dungeon::takeHero(Hero&);
      |                                      ^
main.cpp:1:7: note: forward declaration of 'class Dungeon'
    1 | class Dungeon; // forward declaration
      |       ^~~~~~~

Демонстрация в реальном времени на coliru

Для class Hero необходимо полное объявление class Dungeon, чтобы "знать" его члены.

Для декларации friend class для предварительной декларации достаточно :

class Dungeon; // forward declaration

class Hero {
  friend class Dungeon;
};

class Dungeon {
  public:
    void take(Hero&);
};

Вывод:

(нет) - скомпилировано без жалоб

Живая демоверсия на колиру

...