75

ヘッダー ファイルで前方宣言を使用して使用数を減らし、#includeユーザーがヘッダー ファイルをインクルードするときの依存関係を削減しようとしています。

ただし、名前空間が使用されている場所を宣言することはできません。以下の例を参照してください。

ファイルa.hpp:

#ifndef __A_HPP__
#define __A_HPP__

namespace ns1 {

   class a {
   public:
      a(const char* const msg);

      void talk() const;

   private:
      const char* const msg_;
   };
}

#endif //__A_HPP__

ファイルa.cpp:

#include <iostream>

#include "a.hpp"

using namespace ns1;

a::a(const char* const msg) : msg_(msg) {}

void a::talk() const { 
   std::cout << msg_ << std::endl; 
}

ファイルconsumer.hpp:

#ifndef __CONSUMER_HPP__
#define __CONSUMER_HPP__

// How can I forward declare a class which uses a namespace
//doing this below results in error C2653: 'ns1' : is not a class or namespace name
// Works with no namespace or if I use using namespace ns1 in header file
// but I am trying to reduce any dependencies in this header file
class ns1::a;

class consumer
{
public:
   consumer(const char* const text) : a_(text) {}
   void chat() const;

private:
   a& a_;
};

#endif // __CONSUMER_HPP__

実装ファイルconsumer.cpp:

#include "consumer.hpp"
#include "a.hpp"

consumer::consumer(const char* const text) : a_(text) {}

void consumer::chat() const {
   a_.talk();
}

テストファイルmain.cpp:

#include "consumer.hpp"

int main() {
   consumer c("My message");
   c.chat();
   return 0;
}

更新

以下の回答を使用した非常に不自然な作業コードを次に示します。

ファイルa.hpp:

#ifndef A_HPP__
#define A_HPP__

#include <string>

namespace ns1 {

   class a {
   public:
      void set_message(const std::string& msg);
      void talk() const;

   private:
      std::string msg_;
   };

} //namespace

#endif //A_HPP__

ファイルa.cpp:

#include <iostream>
#include "a.hpp"

void ns1::a::set_message(const std::string& msg) {
    msg_ = msg;
}
void ns1::a::talk() const { 
   std::cout << msg_ << std::endl; 
}

ファイルconsumer.hpp:

#ifndef CONSUMER_HPP__
#define CONSUMER_HPP__

namespace ns1
{
   class a;
}

class consumer
{
public:
   consumer(const char* text);
   ~consumer();
   void chat() const;

private:
   ns1::a* a_;
};

#endif // CONSUMER_HPP__

ファイルconsumer.cpp:

#include "a.hpp"
#include "consumer.hpp"

consumer::consumer(const char* text) {
   a_ = new ns1::a;
   a_->set_message(text);
}
consumer::~consumer() {
   delete a_;
}
void consumer::chat() const {
   a_->talk();
}

ファイルmain.cpp:

#include "consumer.hpp"

int main() {
   consumer c("My message");
   c.chat();
   return 0;
}
4

3 に答える 3

104

a名前空間でクラス型を宣言するには、次のようにしますns1

namespace ns1
{
    class a;
}

複数レベルの名前空間で型を前方宣言するには:

namespace ns1
{
  namespace ns2
  {
    //....
     namespace nsN
     {
        class a;
     }
    //....    
  }
}

具体的な型が必要であることを意味するaメンバーを使用しています。この場合、前方宣言は機能しません。consumer

于 2013-09-25T09:56:14.657 に答える
1

(@billz が言うように) 名前空間内からクラスを前方宣言することとは別に、前方宣言されたクラスを参照するときにその名前空間を使用using(先頭に追加) するか、句を追加することを忘れないでください。

// B.h
namespace Y { class A; } // full declaration of
// class A elsewhere

namespace X {
    using Y::A;   // <------------- [!]
    class B {
        A* a; // Y::A
    };
}

参照:名前空間と前方クラス宣言

于 2018-10-31T09:32:01.787 に答える