假设我有一个私有实施X
的课程Ximpl
:
//X.h
class X
{
void foo();
//..
private:
class Ximpl;
std::unique_ptr<X> x_impl;
}
然后有几种方法来构造代码。也许最常见的是将其他所有内容放入X.cpp
文件中,包括Ximpl
类声明,X
类的方法和方法:
//X.cpp
#include"X.h"
class X::Ximpl
{
void bar();
//..
}
void X::Ximpl::bar()
{
//...
}
void X::foo()
{
//operate on x_impl
}
然而,在不同的来源中提到了其他可能性,它们可以改善代码结构,但可能会降低使用PIMPL习语的优势:
有两个cpp文件:X.cpp
- 只有X
方法的定义,Ximpl.cpp
- 来自Ximpl
类的定义。在X.cpp
的情况下,我们必须#include "Ximpl.cpp"
- 这是一种不好的做法,因为cpp文件将被编译两次
具有单独的头文件Ximpl.h
,它定义了一个实现类,并将Ximpl
和X
类中的所有定义放在单个X.cpp
文件中。在这种情况下,实现类在头文件中声明,并且每次都会重新编译,从而失去了PIMPL的某些优点
最后,有4个单独的文件 - 头文件声明Ximpl
类,第二个头文件声明X
类,以及两个cpp文件,分别实现2个以上的类。
首先,以上都是正确的吗?其次,什么是最佳实践,满足所有要求?它看起来第一种方式(只有1 .h和1 .cpp文件)效果很好,但对于大型代码库,导航项目很快就会变得很麻烦,即单个cpp文件将包含pimpl类declration,pimpl类定义和base类定义。