简体   繁体   English

解决钻石继承问题,但这是否合适?

[英]Solution to diamond inheritance, but is it appropriate?

Aside from the other various things I've been working on, I've also been making an image api. 除了我正在从事的其他工作之外,我还一直在制作图像API。 One problem I've encountered though is the need for there to be an image base class that contains the dimensions of the image. 我遇到的一个问题是需要一个包含图像尺寸的图像基类。 From it would branch ImageIn and ImageOut, and from those come ImageIO. 从中将分支ImageIn和ImageOut,然后从中分支ImageIO。 Here was my original solution; 这是我最初的解决方案;

class ImageBase{
public:
  point<int> Dim() const=0;
};

class ImageI : virtual public ImageBase{
public:
  virtual unsigned int get(int x, int y) const=0;
};

class ImageO : virtual public ImageBase{
public:
  virtual void set(int x, int y, unsigned int col)=0;
};

class ImageIO : public ImageI, public ImageO{
};

class Bitmap : public ImageIO{
  ...
};

Of course, now their are two vtable pointers and dims to each instance of image, and I suppose given the size of an array of pixels, it's probably not worth worrying about, but there is something ascetically displeasing about this, so I purpose this solution; 当然,现在它们是每个图像实例的两个vtable指针和暗淡的颜色,我想给定一个像素数组的大小,可能不值得担心,但是对此有些不满意,所以我打算使用此解决方案;

class ImageIO{ // could also be called ImageBase
public:
  point<int> Dim() const=0;
  virtual unsigned int get(int x, int y) const=0;
  virtual void set(int x, int y, unsigned int col)=0;
};

class ImageI : public ImageIO{
public:
  point<int> Dim() const=0;
  virtual unsigned int get(int x, int y) const=0;
private:
  virtual void set(int x, int y, unsigned int col)=0;
};

class ImageO : public ImageIO{
public:
  point<int> Dim() const=0;
  virtual void set(int x, int y, unsigned int col)=0;
private:
  virtual unsigned int get(int x, int y) const=0;
};

class Bitmap : public ImageIO{
  ...
};

Now, because certain operators in ImageO and ImageI are private, they cannot be accessed from a pointer of that type, accomplishing pretty much what having an input and output edition of a class accomplishes. 现在,由于ImageO和ImageI中的某些运算符是私有的,因此无法从该类型的指针访问它们,从而完成了具有类的输入和输出版本所完成的工作。 There is a slight issue though, the casting syntax is now somewhat more complex. 尽管有一个小问题,强制转换语法现在稍微复杂一些。

ImageI* myImgInput = static_cast<ImageI*>((ImageIO*)(&myReal));

I'm thinking some clever use of casting functions can make the process automatic, so the final question is, are there any inherent flaws in this? 我认为巧妙地使用强制转换功能可以使流程自动化,所以最后一个问题是,这是否有固有的缺陷? I've tested it with a minor implementation, and it works fully, but I'd hate to get the api done, then have to start over. 我已经用一个较小的实现对其进行了测试,并且可以正常运行,但是我不希望将api完成,然后不得不重新开始。

Edit 编辑

Note that what was ImageBase in the second example is now ImageIO for the sake of clarity, and that ImageI and ImageO in the second example were not supposed to virtually inherit from ImageIO 请注意,为了清楚起见,第二个示例中的ImageBase现在为ImageIO,第二个示例中的ImageI和ImageO 不应虚拟继承自ImageIO

This cannot work if the bases have data members 如果基础具有数据成员,则此方法不起作用

Using the following sizes 使用以下尺寸

Imagaebase=4
ImageI=12 + 4 from Imagebase
ImageO=24 + 4 from Imagebase

In the first example the size of Bitmap would be 4 + 12 + 24 (Note Imagebase only counts once) = 40 在第一个示例中, Bitmap的大小为4 + 12 + 24(注意Imagebase仅计数一次)= 40

In the second case the size of Bitmap would be 4 在第二种情况下, Bitmap的大小将为4

Casting would not work if the sizes are so askew 如果尺寸如此歪斜,则铸造将不起作用

If there is no data in any of the classes then: 如果任何类别中都没有数据,则:

The Base should be ImageIO and have all functions in it Base应该是ImageIO并具有所有功能

Then have ImageI and ImageO inherit from it to make the not allowed function(s) to be private. 然后让ImageIImageO继承它,以使不允许的函数私有。 Then there is no casting needed. 则无需铸造。

This would look like the following: 如下所示:

class ImageIO{
public:
  point<int> Dim() const=0;
  virtual unsigned int get(int x, int y) const=0;
  virtual void set(int x, int y, unsigned int col)=0;
};

class ImageI : virtual public ImageIO{
private:
  virtual void set(int x, int y, unsigned int col)
  {
        // Can't be called
  }
};

class ImageO : virtual public ImageIO{
private:
  virtual unsigned int get(int x, int y) const
  {
        // Can't be called
  }
};

class Bitmap : public ImageIO{
  ...
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM