2

我有一个带有 const 字段成员的基本 Image 类:

class Image {
protected:
    const int width;
    const int height;

public:
    virtual ~Image();
    const int getWidth() const;
    const int getHeight() const;

protected:
    Image(const int width, const int height);
};

这意味着在构造函数中,我必须像这样初始化初始化列表中的宽度和高度:

Image::Image(const int width, const int height) :
        width(width), height(height) {
}

现在我打算对其进行子类化,以便我可以通过向子类提供文件路径来加载图像(因此调用代码不必担心加载图像)。此类看起来类似于以下内容:

class GlImage: public Image {
private:
    const GLuint textureId;
    const int textureWidth;     // power of 2 width
    const int textureHeight;    // power of 2 height
    const double textureCoordinateX;
    const double textureCoordinateY;

public:
    GlImage(const string path); // is this constructor possible?
    virtual ~GlImage();
    const double getTextureCoordinateX() const;
    const double getTextureCoordinateY() const;

private:
    // what do we use for initialization functions?
};

但是,我们可以在这里看到 - 在我们获得宽度/高度之前必须加载图像 - 子类中的某些字段也需要在初始化列表中初始化

如何设置子类的构造函数,以便可以初始化所有这些字段?

不可能在子类中引入另一个对象来捕获所有字段数据,将其作为初始化列表中的第一个对象加载,并重新提取所有其他字段的值,因为基类需要宽度/高度(如果图像加载逻辑在派生类中,则不可用)。

是删除 const 修饰符并初始化构造函数中的字段的唯一方法吗?

4

2 回答 2

1

问题是你不能从派生类ctor初始化列表中调用基类构造函数,因为你不知道维度,对吧?

为什么不在派生类上创建静态方法?

class GlImage: public Image {
    ....
    static GlImage LoadFromFile(const string& path)
    {
         // read image data and other info
         int w = ...
         int h = ...
         return GlImage(w, h, ....) 
         // of course, you would need a different ctor in derived class
         // it can even be private
    }
 }
于 2012-12-08T13:28:45.510 回答
0

您可以使用带有可变辅助对象的委托构造函数来执行加载:

class GlImage: public Image {
    ...
    GlImage(const string& path) : GlImage(GlImageLoader(path))
    {
    }

private:
    struct GlImageLoader {
        int w;
        int h;
        GlImageLoader(const string& path) {
            //Read image data
            w = ...;
            h = ...;
        }
    };
    GlImage(GlImageLoader&& l) : Image(l.w, l.h), textureId(l.textureId), ...
    {
    }
};
于 2012-12-09T13:01:17.343 回答