在皮条类中初始化默认值的最佳位置
Best place to initialize default values in a pimpl class?
我非常广泛地使用了PImpl,我发现自己一直在思考如何初始化PImpl结构的成员。选项是为Private
结构创建一个构造函数并在那里初始化它们,或者在主类的构造函数中初始化它们。
myclass.hpp:
class MyClass {
public:
MyClass();
~MyClass();
private:
struct Private; unique_ptr<Private> p;
};
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";
}
目前,我并没有真正看到这两者之间的区别,但如果出于某种原因,我想创建新的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")) {
}
否则,您的Private
成员将是默认构造的,只会在稍后被覆盖(这与int
无关,但更复杂的类型呢?)。
正如@Charles Salvia在上面已经指出的,在两个构造函数中的任何一个中进行赋值都会产生一些开销,因为变量是在赋值之前默认构造的。当然,这种开销的大小很大程度上取决于变量的类型。
如果你能接受这一点,我认为选择可读性最强的版本是最好的。所以,如果你发现MyClass
的构造函数中的赋值是最可读的,那就去做吧
但是,请注意,没有办法绕过初始值设定项列表(对于Private
c'tor),即当您的成员变量没有默认构造函数时,或者当您使用引用或常量时。
您可能想根据具体情况来决定,但"始终"使用初始值设定项列表将使新添加的数据成员保持一致并经得起将来的考验。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 具有默认值的引用获取函数
- 当给定默认值时,为什么此模板参数推导失败
- 从具有默认值的部分指定模板类继承时发生SWIG错误,具有不带默认值的正向声明
- 格式化浮点值:返回默认值
- 如何将数组部分初始化为某个默认值?
- asn1c 不会从 asn.1 模块中提取八位字节字符串的默认值
- 创建一个包含 c++ 默认值的环境文件
- C++(和 ROS) - 包含与前向声明引用,设置默认值和类型定义
- Makefile g++ 使用命令行中的 -D 变量进行编译,默认值
- Switch 语句(字符串)一直选择默认值,除非其为零
- 如何使用默认值将枚举声明为 extern
- 如何在提升程序选项中设置矢量<矢量>的默认值<string>
- 如何使用默认值为构造函数中的枚举赋值?
- 映射唯一值和重复值的有效方法.可以访问键或值的位置
- 变量始终在函数中重置为默认值
- 在皮条类中初始化默认值的最佳位置
- 为什么我总是在传递位置参数时得到默认值
- c++变长函数中默认值参数的位置
- Visual Studios (2012 pro 主要是) <从父级继承或项目默认值的默认值的文件位置>