【问题标题】:constructors calling subclass构造函数调用子类
【发布时间】:2013-10-15 21:02:26
【问题描述】:

我有一个(部分实现的)类层次结构,其中

template<typename T> {
    class data { 
        data ( string s ) {}; // loads from file
        ...
    }
    class image: public data <T> { 
        image ( string s ) {}; // loads from file
        ...
    }
    class jpgimage : public image<T> {
        jpgimage ( string s ) {}; // loads from file 
        ...
    }
    // other image types
}

现在在我的其余代码中,我希望能够抽象出某物是 jpeg 图像还是图像,所以我想使用 data。但同时我想将特定于 jpeg 图像的命令传递给这些函数。

因此,如果我调用data&lt;int&gt; img("lena.jpg");,结果是图像,甚至是 jpeg 图像,我希望数据构造函数调用图像构造函数,而图像构造函数又调用 jpgimage 构造函数。

我无法让它工作,人们警告切片、虚拟构造函数等。但这是一种奇怪的设置方式吗?

【问题讨论】:

  • 这不是 C++。您必须将每个班级设为template
  • 你想要的是Data Factory。您将文件的名称传递给工厂。它计算出要创建的对象类型并返回它。
  • Alexandrescu 的 Modern C++ Design 第 8 章讨论了工厂模式。

标签: c++ subclass superclass object-slicing


【解决方案1】:

继承用于是一个关系。所以,image&lt;T&gt; data&lt;T&gt;,但不是相反!为data&lt;T&gt; 对象调用特定于image&lt;T&gt; 的方法是没有意义的,毕竟它可能不是image&lt;T&gt;。您想要这样做的事实表明您的代码设计存在缺陷。重新考虑您的代码设计。

【讨论】:

  • 点了。我想对其进行编码,例如,我可以加载 image&lt;int&gt; im1("lena.jpg");image&lt;int&gt; im2("lena.png");(对于 PNG 图像使用不同的构造函数),然后将它们用作同一类的对象。所以 jpeg 图像 is 图像和 png 图像 is 图像,但我只想使用加载后它们都是图像的事实。在这种情况下,将不同的 I/O 选项编码为方法而不是不同的类会更好,包括特定于文件类型的部分,例如标头等——这是我认为不同的类最适合的。
  • 我确切地知道你来自哪里。但最好自己考虑一下!
【解决方案2】:

要实现这一点,您需要数据是实现的所有者,而不是基类:

template<typename T> 
class base_data {
    base_data ( string s ) {} // loads from file
    // ...  
};

template<typename T> 
class image: public base_data <T> { 
    image ( string s ) {} // loads from file
    ... 
};

template<typename T> 
class jpgimage : public image<T> {
    jpgimage ( string s ) {} // loads from file 
    // ...
    // other image types
};

template<typename T> 
class data {
    data ( string s ) {
        if(is_jpeg( s )) impl = new jpeg_data<T>( s );
        // ...
    } // loads from file
    // ...
    private:
        base_data<T> *impl;
};

现在在构造函数中你可以创建适当的实现类型等等。

【讨论】:

  • 谢谢。这需要另一个类的事实已经表明这不是一个好主意......
【解决方案3】:

我会说这是一个糟糕的设计。你不需要使用通用的data 类来猜测你是否使用图像,如果你确定你这样做的话。在需要的地方使用imagejpgimage 类,并使用通用的data 类使其他一切工作。

【讨论】:

  • 我让代码更简洁,因为理想情况下我想要的东西可以处理不同形式的数字数据,可以是图像、表面、信号等。我认为 imagejpgimage 类实际上应该只是数据方法。
猜你喜欢
  • 2018-02-28
  • 1970-01-01
  • 2016-05-08
  • 1970-01-01
  • 1970-01-01
  • 2018-05-25
  • 2014-02-19
  • 1970-01-01
  • 2021-09-19
相关资源
最近更新 更多