如何转发声明命名空间中的类
How to forward declare a class which is in a namespace
我正在尝试在头文件中使用前向声明来减少使用的#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;
}
在命名空间中转发声明类类型 a
ns1
:
namespace ns1
{
class a;
}
在多个级别的命名空间中转发声明类型:
namespace ns1
{
namespace ns2
{
//....
namespace nsN
{
class a;
}
//....
}
}
您使用的是a
consumer
的成员,这意味着它需要具体类型,您的前向声明不适用于这种情况。
对于嵌套命名空间,从 C++17 开始,您可以
namespace ns1::ns2::nsN
{
class a;
}
除了从其命名空间中向前声明类(如@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
};
}
参考:命名空间和前向类声明
相关文章:
- 在命名空间 c++ 中正确声明 extern 变量
- 在命名空间中声明变量,在 main 中定义它,使其对所有其他文件可见
- 转发声明在命名空间中不起作用的替代方法
- C++ 17 个友元函数声明和内联命名空间
- 为什么 gcc 无法从其前向声明中检测到友元类命名空间?
- 声明"使用命名空间 C;"对于证明 [namespace.udir]/3 中的示例中显示的结果至关重
- 命名空间内C++变量声明
- 在命名空间中声明变量
- C++ 没有在命名空间外部声明的类主体的类
- 如何在命名空间中声明外部全局,然后定义它?
- 在 c++ 中在运行时声明对命名空间的引用
- 前向声明和全局命名空间声明
- 将命名空间声明为类的友元
- 冗余命名空间声明向量
- c++使用命名空间声明
- 是否有办法配置clang-format使嵌套的命名空间声明保持在同一行
- gSOAP WSSE报头缺少xmlns命名空间声明
- C++ getline() 不需要命名空间声明
- C++命名空间声明和定义
- 使用嵌套命名空间声明"using namespace"时出错 ( "namespace xxx::yyy not allowed in using-declaration" )