C++ C++;在Pimple成语中,是在类之前还是在成员之前转发声明?
大多数Pimpl示例如下所示: 更新:这两种情况都失败,即使用和不使用名称空间。请参阅R Sahu的答案。类Impl必须使用类名C++ C++;在Pimple成语中,是在类之前还是在成员之前转发声明?,c++,namespaces,forward-declaration,pimpl-idiom,incomplete-type,C++,Namespaces,Forward Declaration,Pimpl Idiom,Incomplete Type,大多数Pimpl示例如下所示: 更新:这两种情况都失败,即使用和不使用名称空间。请参阅R Sahu的答案。类Impl必须使用类名siml // Simple.h #include <memory> class Simple { struct Impl; // WORKS! std::unique_ptr<Impl> impl_; public: Simple(); ~Simple(); int get() con
siml
// Simple.h
#include <memory>
class Simple {
struct Impl; // WORKS!
std::unique_ptr<Impl> impl_;
public:
Simple();
~Simple();
int get() const;
};
及
//main.cpp
#包括“Simple.h”
#包括
int main(){
自动无意义=weired::示例::简单{};
std::cout您可以在类内部和类外部转发声明Impl
,而不管Simple
是在命名空间中定义的还是全局定义的
在这两种情况下,Impl
的实现几乎相同
没有命名空间
选项1(Impl
是对等类)
.h文件
struct Impl;
class Simple { ... };
class Simple
{
struct Impl;
...
};
namespace weired::example {
struct Impl;
class Simple { ... };
}
namespace weired::example {
class Simple
{
struct Impl;
...
};
}
.cpp文件
// Define Impl
struct Impl { ... };
// Define Simple
// Define Impl
struct Simple::Impl { ... }; // Need the Simple:: scope here.
// Define Simple
namespace weired::example {
// Define Impl
struct Impl { ... };
// Define Simple
}
namespace weired::example {
// Define Impl
struct Simple::Impl { ... }; // Need the Simple:: scope here.
// Define Simple
}
选项2(Impl
是一个嵌套类)
.h文件
struct Impl;
class Simple { ... };
class Simple
{
struct Impl;
...
};
namespace weired::example {
struct Impl;
class Simple { ... };
}
namespace weired::example {
class Simple
{
struct Impl;
...
};
}
.cpp文件
// Define Impl
struct Impl { ... };
// Define Simple
// Define Impl
struct Simple::Impl { ... }; // Need the Simple:: scope here.
// Define Simple
namespace weired::example {
// Define Impl
struct Impl { ... };
// Define Simple
}
namespace weired::example {
// Define Impl
struct Simple::Impl { ... }; // Need the Simple:: scope here.
// Define Simple
}
使用命名空间
选项1(Impl
是对等类)
.h文件
struct Impl;
class Simple { ... };
class Simple
{
struct Impl;
...
};
namespace weired::example {
struct Impl;
class Simple { ... };
}
namespace weired::example {
class Simple
{
struct Impl;
...
};
}
.cpp文件
// Define Impl
struct Impl { ... };
// Define Simple
// Define Impl
struct Simple::Impl { ... }; // Need the Simple:: scope here.
// Define Simple
namespace weired::example {
// Define Impl
struct Impl { ... };
// Define Simple
}
namespace weired::example {
// Define Impl
struct Simple::Impl { ... }; // Need the Simple:: scope here.
// Define Simple
}
选项2(Impl
是一个嵌套类)
.h文件
struct Impl;
class Simple { ... };
class Simple
{
struct Impl;
...
};
namespace weired::example {
struct Impl;
class Simple { ... };
}
namespace weired::example {
class Simple
{
struct Impl;
...
};
}
.cpp文件
// Define Impl
struct Impl { ... };
// Define Simple
// Define Impl
struct Simple::Impl { ... }; // Need the Simple:: scope here.
// Define Simple
namespace weired::example {
// Define Impl
struct Impl { ... };
// Define Simple
}
namespace weired::example {
// Define Impl
struct Simple::Impl { ... }; // Need the Simple:: scope here.
// Define Simple
}
内部类方法仍将在命名空间内工作;您可能只是在.cpp文件中错误地定义了内部类。您得到的实际错误是什么?struct Simple::Impl{int a,b;};
在Simple.cpp中,而不是struct Impl{int a,b;}
应该做这项工作。请注意,我不能做嵌套的命名空间。这是C++20东西?@user4581301 C++17东西。@Fureeish-Huh。看起来在某个时候,我在IDE的新项目模板中将默认标准设置为11而不是17。谢谢!修复了。是的,想法是在类中私下转发声明,然后你就不需要保护了中的Impl类详细说明了
命名空间,使其对客户端不可见。但是在这种情况下,为什么我可以省略struct Simple::Impl{…}中的简单限定符
如果我的简单类不在名称空间中?所有编译器中都有编译器错误?您是正确的,名称空间大小写和非名称空间大小写是相同的。没有名称空间,我无法再复制成功的编译。一定是某个地方出错了。很抱歉。