我对PImpl进行了大量的使用,我发现自己正在讨论的是准确初始化Pimpl结构的成员.选项是为Private
结构创建构造函数并在那里初始化它们,或者在主类的构造函数中初始化它们.
myclass.hpp:
class MyClass {
public:
MyClass();
~MyClass();
private:
struct Private; unique_ptr<Private> p;
};
Run Code Online (Sandbox Code Playgroud)
myclass.cpp:
#include "myclass.hpp"
#include <string>
struct MyClass::Private {
int some_var;
std::string a_string;
// Option A
Private() :
some_var {42},
a_string {"foo"}
{}
};
MyClass::MyClass() : p(new MyClass::Private) {
// Option B
p->some_var = 42;
p->a_string = "foo";
}
Run Code Online (Sandbox Code Playgroud)
目前我并没有真正看到两者之间的区别,除非我出于某种原因想要创建新Private
对象或复制它们或其他东西,然后选项A可能更好.它还能够初始化初始化列表中的变量,以获得它的价值.但是,我发现选项B往往更具可读性,也许更易于维护.这里有什么东西,我没有看到哪种方式可能会使标尺倾斜?
无论如何,请遵循RAII方法并初始化您的Private
类型中的成员.如果你把东西保存在本地(更重要的是,在逻辑位置),维护将会感谢你.更重要的是,如果使用选项A,您将能够拥有const成员.
如果必须从MyClass
ctor 传递值,那么请为以下内容创建一个合适的构造函数Private
:
struct MyClass::Private {
int const some_var; // const members work now
std::string a_string;
// Option C
Private(int const some_var, std::string const& a_string) :
some_var {some_var},
a_string {a_string}
{}
};
MyClass::MyClass() : p(new MyClass::Private(42,"foo")) {
}
Run Code Online (Sandbox Code Playgroud)
否则你的Private
成员将被默认构造,只是稍后被覆盖(这与int
s 无关,但更复杂的类型呢?).