C++ 如何转发声明位于命名空间中的类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19001700/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to forward declare a class which is in a namespace
提问by Angus Comber
I am trying to use forward declarations in header files to reduce #includes used and hence reduce dependencies where users include my header file.
我试图在头文件中使用前向声明来减少 #includes 的使用,从而减少用户包含我的头文件的依赖关系。
However, I am unable to forward decalre where namespaces are used. See example below.
但是,我无法在使用命名空间的地方转发 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;
}
UPDATE:
更新:
Here is my very contrived working code using the answer below.
这是我使用下面的答案非常人为的工作代码。
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;
}
回答by billz
To forward declare class type a
in a namespace ns1
:
a
在命名空间中转发声明类类型ns1
:
namespace ns1
{
class a;
}
To forward declare a type in multiple level of namespaces:
要在多级命名空间中转发声明类型:
namespace ns1
{
namespace ns2
{
//....
namespace nsN
{
class a;
}
//....
}
}
Your are using a
a member of consumer
which means it needs concrete type, your forward declaration won't work for this case.
您使用a
的成员consumer
意味着它需要具体类型,您的前向声明不适用于这种情况。
回答by Campa
Apart to forward-declare the class from within its namespace (as @billz says), remember to either use(prepend) that namespace when referring to the forward-declared class, or add a using
clause:
除了从其命名空间中向前声明类(如@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: Namespaces and Forward Class Declarations
参考:命名空间和前向类声明
回答by user2193043
For nested namespaces, since C++17, you can do
对于嵌套命名空间,从 C++17 开始,你可以这样做
namespace ns1::ns2::nsN
{
class a;
}