繁体   English   中英

C++ 在 Pimple 习语中的类之前或成员之前的前向声明?

[英]C++ Forward declaration before class or before member in the Pimple idiom?

大多数Pimpl示例如下所示:

更新:两种情况都失败,即有和没有命名空间。 请参阅 R Sahu 在https://stackoverflow.com/a/57103016/2712726 上的回答。 类 Impl 必须用类名Simpl限定

// Simple.h
#include <memory>
class Simple {
     struct Impl; // WORKS!
     std::unique_ptr<Impl> impl_;
     public:
     Simple();
     ~Simple();
     int get() const;
};

但这在您将使用名称空间的现实世界中似乎失败了。 当存在命名空间时,前向声明必须移动到类声明之前。 谁能解释为什么?

// Simple.h but now with name spaces
namespace weired::example {
    struct Impl; // OK! forwad declaration must go here
    class Simple {
         //struct Impl; // ERROR! incomplete type in ctor definition
         std::unique_ptr<Impl> impl_;
         public:
         Simple();
         ~Simple();
         int get() const;
    };
}

我已经用gcc9clang8测试了这个-std=c++11c++2a 为了完整起见,这里是 Simple.cpp 和 main.cpp 文件,因此您可以自己运行示例:

// Simple.cpp
#include "Simple.h"
namespace weired::example {

    struct Impl {int a,b;};

    Simple::Simple() : impl_(new Impl{3,4}) {}       

    Simple::~Simple() = default;

    int Simple::get() const
    {
        return impl_->a;
    }
}

// main.cpp
#include "Simple.h"
#include <iostream>

int main () {       
        auto nonsense = weired::example::Simple{};
        std::cout << nonsense.get() << '\n';
}   

您可以在类内部和类外部转发声明Impl ,无论Simple是在命名空间中定义还是在全局定义。

在这两种情况下, Impl的实现几乎相同。

没有namespace

选项 1( Impl是同级类)

.h 文件

struct Impl;
class Simple { ... };

.cpp 文件

// Define Impl
struct Impl { ... };

// Define Simple

选项 2( Impl是嵌套类)

.h 文件

class Simple
{
   struct Impl;
   ...
};

.cpp 文件

// Define Impl
struct Simple::Impl { ... };  // Need the Simple:: scope here.

// Define Simple

namespace

选项 1( Impl是同级类)

.h 文件

namespace weired::example {

   struct Impl;
   class Simple { ... };
}

.cpp 文件

namespace weired::example {

   // Define Impl
   struct Impl { ... };

   // Define Simple
}

选项 2( Impl是嵌套类)

.h 文件

namespace weired::example {

   class Simple
   {
      struct Impl;
      ...
   };
}

.cpp 文件

namespace weired::example {

   // Define Impl
   struct Simple::Impl { ... };  // Need the Simple:: scope here.

   // Define Simple
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM