【发布时间】:2017-02-09 17:00:57
【问题描述】:
我正在使用 C++ 编程并尝试使用不可变数据类型作为学习新事物的一种方式,而且还因为有人告诉我使用不可变数据类型可以更容易地推断代码的影响,因为您知道实例一旦被构造就不能改变。
我经常想使用分支逻辑创建一个数据实例。例如:
int x = 0;
if (a)
{
x = 1;
}
else
{
if (b)
{
x = 2;
}
else
{
x = 3;
}
}
DoSomething(x);
但是,如果我的数据类型是不可变的,则该代码将无法编译,因为不能有复制赋值运算符:
struct Immutable
{
public:
const int x;
Immutable(const int x)
: x(x)
{}
}
Immutable x(0);
if (a)
{
x = Immutable(1); // Compiler error
...
我可以想到 2 种可能的解决方案。首先,我可以使用三元运算符根据条件构造我的数据:
Immutable x = a ? Immutable(1) : (b ? Immutable(2) : Immutable(3));
但这很快就会导致复杂的语法。
或者,我可以使用std::unique_ptr:
std::unique_ptr<Immutable> x = nullptr;
if (a)
{
x = std::unique_ptr<Immutable>(new Immutable(1));
}
else
{
if (b)
{
x = std::unique_ptr<Immutable>(new Immutable(2));
}
else
{
x = std::unique_ptr<Immutable>(new Immutable(3));
}
}
DoSomething(*x);
但在我看来,这可能首先否定了使用不可变数据的好处。
最后,我尝试做的事情可能没有意义,我应该只使用可变数据类型。
什么是获得不变性好处的正确技术?
【问题讨论】:
-
为什么不简单地将
const int x;隐藏为私有成员int x;并且不允许通过任何公共/受保护的成员函数进行更改? -
@tobi303 我不想在构造后对其进行变异,但我希望构造依赖于我的分支逻辑。或者,我想我可以在我的分支逻辑中改变构造函数参数,然后在最后的一行中构造一个实例。
-
在不改变界面的情况下,
std::uniqe_ptr<Immutable>解决方案看起来最直接的 IMO。 -
@Ryan 除了机制之外,您能否提供一个更好的具体用例示例(edit 在您的问题中)。
-
@Dan 不是。但解释了我在第一条评论中的意思。
标签: c++ immutability