【发布时间】:2011-03-28 18:37:28
【问题描述】:
我想创建一个不可变的数据结构,比如说,可以从文件初始化。
class Image {
public:
const int width,height;
Image(const char *filename) {
MetaData md((readDataFromFile(filename)));
width = md.width(); // Error! width is const
height = md.height(); // Error! height is const
}
};
我可以做些什么来解决这个问题
class Image {
MetaData md;
public:
const int width,height;
Image(const char *filename):
md(readDataFromFile(filename)),
width(md.width()),height(md.height()) {}
};
然而
- 它迫使我将 MetaData 作为一个字段保存在我的对象中。我并不总是想要。
- 有时构造函数中的逻辑比单次读取要复杂得多(例如,错误处理可能需要几行代码)
所以我想到的唯一解决方案是
class A {
int stub;
int init(){/* constructor logic goes here */}
A():stub(init)/*now initialize all the const fields you wish
after the constructor ran */{}
};
有更好的主意吗? (在Java 中,您可以在构造函数中初始化finals)。
【问题讨论】:
-
为什么Image的成员必须是
const?一个不可变的数据结构最好用一个数据结构类的const实例来表示,而不是一个所有成员恰好都是const的数据结构类的实例。如果您遵循这种方法,那么您的构造函数中没有任何问题;对象的const-ness 仅在构造函数完成后才开始。 -
差不多这个 - 不要让成员变量 const,真的。
-
@Charles,我希望所有图像都尽可能 const。我不希望在我之后的任何程序员在
Image中的方法中更改对象的大小。我不想跟踪谁更改了这个图像大小,如果两个位置的图像大小不同,我可以断定这是 100% 的内存泄漏,而不是一个懒惰的程序员制作快捷方式。有很多正当理由偏爱强制和通信某个领域一定不能改变。 -
也许改变构造函数接受宽度和高度作为参数可以解决问题。
-
@Elazar Leibovich:我真的不明白你在保护什么。如果人们要在不与您交流的情况下编辑您的课程(添加方法),那么他们要做的第一件事就是在
const妨碍他们时立即删除它。对我来说,感觉就像你正在尝试设计更适合你如何使用你的类而不是如何使用它的限制。
标签: c++ constructor constants