3

I have a namespace defined in one header file and used in another, but it cannot be found. Specifically, a namespace called "players" defined in "players/Players.hpp" and used in a file called "players/Ownable.hpp" cannot be found in a file called "combat/Targetable.hpp"

The errors are

...\source\combat\Targetable.hpp(7): 'players' : is not a class or namespace name
...\source\combat\Targetable.hpp(7): 'Ownable' : base class undefined

Obviously it's some syntax thing I don't understand. I've spent some time simplifying the code so it looks silly, but bear with me.

// source/players/Players.hpp:
#ifndef PLAYERS_HPP
#define PLAYERS_HPP

#include "../Headers.hpp"

namespace players {
  class Player{

// this class compiles fine.
// There used to be a "Players.cpp" but it's been simplified away

    public:
      int getID(){ return 0; }
      int getTeam(){ return 0; }
      string getName(){ return ""; }
      Vec3 getColor(){ return Vec3(0.0,0.0,0.0); }
  };
}
#endif

And players/Ownable.hpp, which is in the same folder as Player.hpp and also compiles fine:

// source/players/Ownable.hpp:
#ifndef OWNABLE_HPP
#define OWNABLE_HPP

#include "Players.hpp"

namespace players {
  class Ownable;
  typedef boost::shared_ptr<Ownable> OwnablePTR;
  typedef boost::weak_ptr<Ownable> OwnableWPTR;

  class Ownable {
    public:
      Ownable(){}
      Ownable(int playerID) : playerID(playerID){}
      bool isAlliedWith(OwnablePTR other){ return false; }

    private:
      int playerID;
  };
}

#endif

Here's where the fun starts. I have a file at "source/combat/Targetable.hpp", which is in a different directory than the other two. However, the file itself seems to include fine:

// source/combat/Targetable.hpp:
#ifndef TARGETABLE_HPP
#define TARGETABLE_HPP

#include "../players/Ownable.hpp"

namespace combat{
  class Targetable : public players::Ownable { // ERROR
    public:
      Targetable(int playerID){}
      //Targetable(players::Player player);

      virtual Vec2 getPosition(){
        return Vec2();
      }
      virtual Vec2 getVelocity(){
        return Vec2();
      }
  };
}

#endif

I'm really hoping this is some silly syntax thing that I'm missing. I've even tried

using players::Ownable;

but that A) pollutes the files that include this one, and B) doesn't fix anything. Any help?

EDIT: GManNickG got it, it was a circular include in the Headers.hpp file. Thanks!

4

2 に答える 2

4

サーキュラーインクルードがあります。

まず、警備員を含める目的を検討します。

// a.hpp
#ifndef A_HPP
#define A_HPP

// stuff

#endif

 

// b.hpp
#ifndef B_HPP
#define B_HPP

#include "a.hpp"

// stuff

#endif

 

// c.hpp
#ifndef C_HPP
#define C_HPP

#include "a.hpp"
#include "b.hpp"

// stuff

#endif

 

// x.cpp
#include "c.hpp"

を含めると、 2回含まれることにc.hppなります。a.hpp1回目はガードが定義されておらず、すべてが正常であり、2回目はガードが再定義を防ぎます。これが私たちが望んでいることです。

ただし、ループがある場合は機能しません。(それはそれを防ぎます、それは良いです、しかしそれはガードがテストされた直後に定義されるので「あまりにもよく」します、それはヘッダーの内容が実際にまだ処理されていないことを意味します)。代わりにこれを検討してください:

// a.hpp
#ifndef A_HPP
#define A_HPP

#include "c.hpp"

// stuff

#endif

 

// b.hpp
#ifndef B_HPP
#define B_HPP

#include "a.hpp"

// stuff

#endif

 

// c.hpp
#ifndef C_HPP
#define C_HPP

#include "b.hpp"

// stuff

#endif

 

// x.cpp
#include "c.hpp"

これはあなたが持っているものに似ています。x.cppincludec.hppは、初めて含まれるため、を定義しますC_HPP。次に、を含みc.hppます。これには。が含まれます。次に、すでに定義されているインクルードと検索を行うため、インクルードは何もしません。b.hppa.hppa.hppc.hppC_HPP

a.hppまだコンパイルに成功していると仮定すると(つまり、c.hpp実際には必要ありません)、次にa.hpp終了し、次にb.hpp終了し、c.hpp最後に実際にその内容を定義してからに戻りx.cppます。

解決策は、含めるヘッダーの量を最小限に抑えることです。前方宣言を使用し、何よりも、「すべてを含める」ヘッダーを使用しないでください。これらはひどいです。そして、私はそれが何であるかを疑っていHeaders.hppます。

于 2012-04-17T19:03:41.617 に答える
1

どうclass Targetable : public ::players::Ownable { . . .ですか?

::の前 のグローバル名前空間の修飾に注意してくださいplayers

于 2012-04-17T05:40:52.477 に答える