[英]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;
};
}
我已经用gcc9
和clang8
测试了这个-std=c++11
到c++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
Impl
是同级类).h 文件
struct Impl;
class Simple { ... };
.cpp 文件
// Define Impl
struct Impl { ... };
// Define Simple
Impl
是嵌套类).h 文件
class Simple
{
struct Impl;
...
};
.cpp 文件
// Define Impl
struct Simple::Impl { ... }; // Need the Simple:: scope here.
// Define Simple
namespace
Impl
是同级类).h 文件
namespace weired::example {
struct Impl;
class Simple { ... };
}
.cpp 文件
namespace weired::example {
// Define Impl
struct Impl { ... };
// Define Simple
}
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.