【发布时间】:2013-06-12 19:29:06
【问题描述】:
来自 C# 背景,我习惯于使 结构不可变。
因此,当我开始使用 C++ 编程时,我尝试对通常按值传递的类型进行相同的处理。
我有一个简单的结构,它代表一个自定义索引并简单地包装一个整数。因为在 C++ 中,const 关键字有点类似于 C# 中的 readonly,所以像这样实现我的结构似乎是合理的:
struct MyIndex
{
MyIndex(int value) :
Value(value)
{
}
const int Value;
};
这种方法的问题在于,该结构的行为与 C# 中的不可变结构完全不同。不仅MyIndex变量的Value字段不能修改,任何现有的MyIndex变量(局部变量或字段变量)甚至都不能用另一个MyIndex-instance替换。
因此以下代码示例无法编译:
a) 使用索引作为循环变量。
MyIndex index(0);
while(someCondition)
{
DoWork();
index = MyIndex(index.Value + 1); // This does not compile!
}
b) 修改MyIndex类型的成员字段
class MyClass
{
MyIndex Index;
void SetMyIndex(MyIndex index)
{
Index = index; // This does not compile!
}
};
这两个示例不编译,编译错误是一样的:
错误 C2582:“MyIndex”中的“operator =”函数不可用
这是什么原因?为什么变量不能用另一个实例替换,尽管它们不是const?构建错误意味着什么? operator = 函数是什么?
【问题讨论】:
-
C# 中的结构和 C++ 中的结构非常不同。我认为这个问题不适用于 C++。
-
在 C++ 中,struct 和 class 是一样的,它们都更像 C# struct 而不是 C# classes。
-
@SLaks:整个问题是 C++,问题是“如何在 C++ 中制作类似 java 的不可变结构”
-
使用复制构造函数似乎完全违反了不可变对象 IMO。这样做的正确方法不是涉及
std::shared_ptr吗?事实上javapractices.com/topic/TopicAction.do?Id=29 提到“不需要复制构造函数” -
我对 C++ 不是很熟悉,但我认为 C# 中所谓的“不可变”结构等同于只有私有(但非 const)字段的 C++ 结构,并且只允许通过方法或只读属性读取这些字段的值[我不知道属性是 C++ 标准的一部分还是 MS 扩展]。请注意,在 .NET 中并没有真正的不可变结构类型之类的东西——只有使突变变得方便的结构和使突变变得尴尬的结构。
标签: c++ immutability