如何转发声明名称空间中的类

Ang*_*ber 38 c++ namespaces

我试图在头文件中使用前向声明来减少使用的#includes,从而减少用户包含我的头文件的依赖关系.

但是,我无法转发使用命名空间的decalre.见下面的例子.

a.hpp file:
#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 file:
#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 file:
#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 implementation file:
#include "consumer.hpp"
#include "a.hpp"

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

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

test - main.cpp file:
#include "consumer.hpp"

int main() {
   consumer c("My message");
   c.chat();
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

更新:

这是我非常做作的工作代码,使用下面的答案.

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;
}
Run Code Online (Sandbox Code Playgroud)

bil*_*llz 57

a在名称空间中转发声明类类型ns1:

namespace ns1
{
    class a;
}
Run Code Online (Sandbox Code Playgroud)

要在多级命名空间中转发声明类型:

namespace ns1
{
  namespace ns2
  {
    //....
     namespace nsN
     {
        class a;
     }
    //....    
  }
}
Run Code Online (Sandbox Code Playgroud)

您使用a的成员consumer意味着它需要具体类型,您的前瞻性声明将不适用于此案例.

  • 或`class :: ns1 :: a;` (6认同)
  • +1:自从我愤怒地编写C++以来,它很容易10年,但我立即知道答案,只需重新声明命名空间.我很高兴我记得,我已经忘记了很多其他的事情... (4认同)
  • @Thomas,我刚刚尝试过并得到了'错误C3083:'ns1':'::'左边的符号必须是一个类型` (3认同)
  • @Thomas我相信只有在命名空间已经存在的情况下才有效. (2认同)
  • @Iron不仅必须存在该命名空间,而且必须在其中声明该类,在这种情况下,在命名空间之外重新声明该类几乎没有意义. (2认同)

小智 17

对于嵌套命名空间,从 C++17 开始,你可以这样做

namespace ns1::ns2::nsN
{
  class a;
}
Run Code Online (Sandbox Code Playgroud)

  • 只使用“class ns1::ns2::nsN::a”怎么样? (4认同)