Ela*_*ich 8 c++ constructor const
我想创建一个不可变的数据结构,例如,可以从文件初始化.
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
}
};
Run Code Online (Sandbox Code Playgroud)
我能做些什么来解决这个问题
class Image {
MetaData md;
public:
const int width,height;
Image(const char *filename):
md(readDataFromFile(filename)),
width(md.width()),height(md.height()) {}
};
Run Code Online (Sandbox Code Playgroud)
然而
所以我想到的唯一解决方案是沿着这条线
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 */{}
};
Run Code Online (Sandbox Code Playgroud)
有更好的主意吗?(在Java,你可以final在构造函数中初始化s).
Geo*_*che 11
你可以移动width并height进入一个类型和初始化代码进入初始化辅助函数:
// header:
struct Size {
int width, height;
Size(int w, int h) : width(w), height(h) {}
};
class Image {
const Size size; // public data members are usually discouraged
public:
Image(const char *filename);
};
// implementation:
namespace {
Size init_helper(const char* filename) {
MetaData md((readDataFromFile(filename)));
return Size(md.width(), md.height());
}
}
Image::Image(const char* filename) : size(init_helper(filename)) {}
Run Code Online (Sandbox Code Playgroud)
你可以在NamedConstructor这里简单地使用这个成语:
class Image
{
public:
static Image FromFile(char const* fileName)
{
MetaData md(filename);
return Image(md.height(), md.width());
}
private:
Image(int h, int w): mHeight(h), mWidth(w) {}
int const mHeight, mWidth;
};
Run Code Online (Sandbox Code Playgroud)
命名构造函数的一个主要优点是它们的显而易见性:名称表示您正在从文件构建对象.当然它稍微冗长一点:
Image i = Image::FromFile("foo.png");
Run Code Online (Sandbox Code Playgroud)
但这从来没有困扰过我.
如果是 C++0x,我会推荐这个(委托构造函数):
class Image
{
public:
const int width, height;
Image(const char* filename) : Image(readDataFromFile(filename)) { }
Image(const MetaData& md) : width(md.width()), height(md.height()) { }
};
Run Code Online (Sandbox Code Playgroud)
您可以放弃构造函数中的常量:
class Image {
public:
const int width,height;
Image(const char *filename) : width(0), height(0) {
MetaData md(readDataFromFile(filename));
int* widthModifier = const_cast<int*>(&width);
int* heightModifier = const_cast<int*>(&height);
cout << "Initial width " << width << "\n";
cout << "Initial height " << height << "\n";
*widthModifier = md.GetWidth();
*heightModifier = md.GetHeight();
cout << "After const to the cleaners " << width << "\n";
cout << "After const to the cleaners " << height << "\n";
}
};
Run Code Online (Sandbox Code Playgroud)
这将实现你想做的事情,但我必须说我个人会远离它,因为它会导致根据标准的未定义行为(摘自cppreference)
const_cast 可以形成对实际上引用 const 对象的非常量类型的引用或指针...通过非常量访问路径修改 const 对象...会导致未定义的行为。
我担心任何公共数据成员(至少在您的特定示例中)。我会采用 Georg 的方法,或者将数据设为私有并仅提供吸气剂。