当前位置: 首页 > 知识库问答 >
问题:

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

杜哲彦
2023-03-14

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

但是,我无法在使用名称空间的地方转发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;
}

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

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;
}

共有3个答案

叶越
2023-03-14

除了从类的名称空间中向前声明类之外(正如@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
    };
}

ref:命名空间和转发类声明

姜智渊
2023-03-14

对于嵌套名称空间,从C++17开始,您可以

namespace ns1::ns2::nsN
{
  class a;
}
林玮
2023-03-14

在命名空间ns1中转发declare类类型a:

namespace ns1
{
    class a;
}

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

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

您正在使用aconsumer的成员,这意味着它需要具体的类型,您的前向声明在这种情况下不起作用。

 类似资料:
  • 如何在命名空间中转发声明类。例如,下面是一个库的头文件,用户不需要知道私有的myPtr,所以当包含在头文件下面时,不需要包含boost头文件。那么我如何向前声明boost::shared_ptr以启用用户代码编译呢? MyClass.h

  • 我有困难建立一个有3个类的结构。我不确定包含/转发声明。 下面的代码一直在编译,直到我在inclino.h中添加名称空间和枚举。我从Inclinomeasure.h收到“Inclino尚未声明”。 倾斜度。h 倾斜度 倾角读数.h 结构正确吗?如何访问其他类中的枚举? 提前道谢。 编辑:我修复了名称空间的问题,把它放在一个新的文件,包括由3类。但我似乎误用了include/forward声明。

  • 问题内容: 如何在JavaScript中创建名称空间,以使我的对象和函数不会被其他同名对象和函数覆盖?我使用了以下内容: 有没有更优雅或更简洁的方法? 问题答案: 我喜欢这个:

  • 在调用axis2 1.7.5(Wsdl2Java)生成的存根时,有人知道如何解决以下问题吗? 我发现存根发送了以下请求,但没有添加/定义SOAP版本(xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/)这是问题的根源 因此,我尝试如下设置SoapVersionURL 甚至可以直接将存根中的名称空间设置为 但是,这两种方法仍然忽略“xml

  • 这是一个非常基本的问题,但实际上我从来没有自己定义过名称空间。我正在尝试将我的基于Qt的库中的类分组在各种名称空间中(并且还允许更容易的扩展而不发生名称冲突)。例如,主类(也表示库)属于顶级命名空间: 这个使用了一组其他名称空间和类,这些名称空间和类是在的头文件中定义的,这些头文件包含在的头文件中: 其中Manager.h包含 和configurator.h包含 类的内容在这里并不重要。 在编译时

  • 我正在创建一个基于以下代码的动态sitemap.xml 这是可行的,但Google不高兴“urlset”节点中没有Namespace声明。Google错误:“您的Sitemap或Sitemap索引文件未声明预期的命名空间:http://www.sitemaps.org/schemas/sitemap/0.9" 如果我将代码更改为: 它无法生成xml文件并引用以下内容: 在测试中,我发现节点需要一个