在std命名空间中变量/类的前置声明

20

通常我主要使用前向声明,在.hpp文件中不需要完整定义的类。

例如:

 //B.hpp

 namespace A_file {
   class A;
 }

 namespace B_file {

  class B {
   public:
        B();
   private:
        A *ptr_to_A;
  }
 }

 //B.cpp

 #include "A.hpp"
 using namespace A_file;

 namespace B_file {

   B(int value_) {
        *ptr_to_A = new A(value_);
   }

   int some_func() {
        ptr_to_A->some_func_in_A();
   }
 }

我写了这样的代码。我认为,这样做可以避免再次包含整个 hpp 文件。(如果您觉得这不好,请随意评论)

是否有一种方法可以对 std 命名空间中的对象/类执行相同的操作?如果有,这样做是否安全或会产生副作用?

1个回答

33

为了节省编译时间,您可以在头文件中前向声明自己的类。但是不能对命名空间std中的类进行前向声明。根据C++11标准17.6.4.2.1:

除非另有规定,否则如果程序将声明或定义添加到命名空间std或命名空间中的命名空间,则C++程序的行为未定义。

请注意,其中一些类是模板类的typedef,因此简单的前向声明将无法工作。例如,您可以使用#include<iosfwd>而不是#include<iostream>,但是没有类似的头文件仅具有stringvector等的前向声明。

有关更多信息,请参见GotW#34,前向声明


6
可预见的是,<iosfwd> 奠定的先例也是最佳实践:应该优先使用额外的前向声明头文件,由“正常”头文件包含以获取编译时检查来保证持续有效性,并由仅需要前向声明的客户端包含。它应该与代码进行前向声明的库一起“存在”并进行维护,而不是与客户端代码一起!上面的 GotW 给出了确切的原因:结构体可能成为模板的 typedef,模板可能添加参数等。 - Tony Delroy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接