1

質問: ヘッダーで定義されている他の名前空間/クラスを非表示にしながら、ヘッダーから特定のクラスにアクセスすることは可能ですか?

たとえば、ヘッダー ファイルoutput.hppがあるとします。

// outcome.hpp
namespace sports { namespace outcome {
  class Injury {};
  class Success {};
}}

別のヘッダー ファイル ( api.hpp ) では、 api.hppを含むファイルにアクセスsports::outcome::Injuryせずに使用したいと考えています。それは可能ですか?もしそうなら、どうすればそれを達成できますか?sports::outcome::Success

PS 実際のコードでは、api.hppには、クラスのメソッドを呼び出すテンプレート化されたメソッドが含まれてInjuryいるため、前方宣言では不十分です。


私の試み:

私の無知でinclude、内部名前空間内に配置することでこれを達成しようとしました。SSCCEは次のとおりです。

// api.hpp
namespace sports { namespace api {
  namespace internal {
    #include "outcome.hpp"  // I'm trying to hide symbols within this header
    using sports::outcome::Injury;
  } 

  class Boxing {
    private:
      internal::Injury sustained;
  };
}

それがうまくいったとき、私は時期尚早に祝いました:

// This cpp file compiles file   \o/
#include "api.hpp"
int main(int argc, char *argv[]) {
  sports::api::Boxing b;  
  // sports::outcome not accessible
}

失敗する方法:

標準ライブラリのコンテナーがoutput.hppのクラス メンバーとして使用されている場合、事態は崩壊します。たとえば、次のバージョンを使用します。

// outcome.hpp
#include <vector>
namespace sports { namespace outcome {

  class Injury {
    private:
      std::vector x;
  };

// ...
}}

コンパイルは次のエラーで失敗します:

/usr/include/c++/4.6/ext/new_allocator.h:34:0 からインクルードされたファイルで、
                 /usr/include/c++/4.6/x86_64-linux-gnu/./bits/c++allocator.h:34 から、
                 /usr/include/c++/4.6/bits/allocator.h:48 から、
                 /usr/include/c++/4.6/vector:62 から、
                 output.hpp:1 から、
                 api.hpp:5 から、
                 main.cpp:1 から:
/usr/include/c++/4.6/new:93:54: エラー: 'void* sports::api::internal::operator new(sports::api::internal::std::size_t)' ではない可能性があります名前空間内で宣言された
/usr/include/c++/4.6/new:94:56: エラー: 'void* sports::api::internal::operator new [](sports::api::internal::std::size_t)' かもしれません名前空間内で宣言しない
/usr/include/c++/4.6/new:95:35: エラー: 'void sports::api::internal::operator delete(void*)' は名前空間内で宣言されていない可能性があります
/usr/include/c++/4.6/new:96:37: エラー: 'void sports::api::internal::operator delete [](void*)' は名前空間内で宣言されていない可能性があります
/usr/include/c++/4.6/new:97:62: エラー: 'void* sports::api::internal::operator new(sports::api::internal::std::size_t, const sports:: api::internal::std::nothrow_t&)' は名前空間内で宣言できません
/usr/include/c++/4.6/new:98:64: エラー: 'void* sports::api::internal::operator new [](sports::api::internal::std::size_t, const sports ::api::internal::std::nothrow_t&)' は名前空間内で宣言できません
/usr/include/c++/4.6/new:99:58: エラー: 'void sports::api::internal::operator delete(void*, const sports::api::internal::std::nothrow_t&)'名前空間内で宣言することはできません
/usr/include/c++/4.6/new:100:60: エラー: 'void sports::api::internal::operator delete [](void*, const sports::api::internal::std::nothrow_t& )' は名前空間内で宣言できません
/usr/include/c++/4.6/new:103:57: エラー: 'void* sports::api::internal::operator new(sports::api::internal::std::size_t, void*)'名前空間内で宣言することはできません
/usr/include/c++/4.6/new:104:59: エラー: 'void* sports::api::internal::operator new [](sports::api::internal::std::size_t, void* )' は名前空間内で宣言できません
/usr/include/c++/4.6/new:107:52: エラー: 'void sports::api::internal::operator delete(void*, void*)' は名前空間内で宣言されていない可能性があります
/usr/include/c++/4.6/new:108:52: エラー: 'void sports::api::internal::operator delete [](void*, void*)' は名前空間内で宣言されていない可能性があります

私は明らかにこれを間違っています。アドバイスと良い報告をいただければ幸いです。

4

2 に答える 2

1

using 宣言を使用して、名前空間から別の名前空間に名前をインポートできます。

namespace sports {
  using sports::outcome::Injury;
};

あなたの例では、多くのことが間違っています。特に、インクルードの配置が不適切であり、インクルード ガードが不足しています。

// file1.h
#ifndef FILE1_h
#define FILE1_h

namespace sports { namespace outcome {
  class Injury;
}}
#endif

// api.h   
#ifndef API_H
#define API_H

#include <file1.h>

namespace sports {
  using sports::outcome::injury;
}

#endif

を含むファイルは、api.h次のものにアクセスできるようになりました。

sports::injury x;

インクルードだけのファイルは、次のものにfile1.hのみアクセスできます。

sports::outcome::injury x;
于 2012-11-14T16:19:41.943 に答える
0

私があなたの意図を正しく理解していれば、「プライベート」または「内部」名前空間のようなものが必要ですか? C ++では不可能な私見。

クラスを使用してこれを行い、内部クラス定義をそこにネストされたクラスとして配置すると、api が内部クラスのフレンドである場合、api 名前空間を同様に実現して、他のクラスを public typedef として公開できます。

namespace sports
{
    class api;

    class outcome
    {
        friend class api;

        // Internal class definitions
        class Boxing
        {
        };
    };

    class api
    {
    public:
        typedef outcome::Boxing Boxing;
    }
}
于 2012-11-14T16:31:55.023 に答える