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

我试图在头文件中使用转发声明来减少使用的 #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;
}
76316 次浏览

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

namespace ns1
{
class a;
}

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

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

你使用的是 aconsumer的一个成员,这意味着它需要具体的类型,你的前向声明不适用于这种情况。

除了在其名称空间内向前声明类(如@bilz 所说)之外,在引用向前声明的类时,请记住要么 使用(预置)该名称空间,要么添加一个 using子句:

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


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

档号: 命名空间和转发类声明

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

namespace ns1::ns2::nsN
{
class a;
}