具有不同数组实现的子类

发布于 2024-10-16 11:41:18 字数 962 浏览 1 评论 0原文

假设我有一个基类模板 MyBase:

template <class T>
class MyBase{
private:
    T data;
public:
    MyBase(T _data);
};

我想将其子类化两次(至少现在):

  1. 数据应该是动态二维数组:T **data
  2. 数据应该是固定的 2维数组:T data[rows][cols]

我对 C++ 还是个新手,我不知道如何做到这一点。 具体来说,我想制作一种矩阵库(主要作为一个学习项目)。我过去做过一些事情,动态存储矩阵更有意义,反之亦然。因此,似乎一个好的解决方案是实现一个提供所有常用功能的基类(例如,应该使用 data [i][j] = item;(无论哪种情况),然后子类化 DynamicMatrix 和 FixMatrix。 DynamicMatrix 将有一个构造函数,该构造函数执行

data = new T*[rows];
for (int i = 0; i < rows; i++)
{
    data[i] = new T[cols];
}
for (int i = 0; i < rows; i++)
{
    for (int j = 0; j < cols; j++)
    {
         data[i][j] = 0;
    }
}

And FixMatrix 只是:

for (i=0; i < rows; i++)
{
    for (j=0; j < cols; j++)
    {
         data[i][j] = 0;    
    }
}

在基类中创建成员变量 T data; 非常容易。但是在子类中,如何将其转换为双指针?或许我不能,我可以接受。但那我该怎么办呢?

Let's say I have a base class template MyBase:

template <class T>
class MyBase{
private:
    T data;
public:
    MyBase(T _data);
};

I want to subclass this twice (at least for now):

  1. data should be a dynamic 2-dimensional array: T **data
  2. data should be a fixed 2-dimensional array: T data[rows][cols]

I'm still a bit of a novice with C++, and I can't figure out how to do this.
Specifically, I want to make a sort of matrix library (primarily as a learning project). I've done some things in the past where having my matrix stored dynamically made more sense, and vice versa. So, it seems like a good solution would be to implement a base class that provides all the common functionality (insert(T item, int i, int j), for example, should use data[i][j] = item; in either case), then subclass a DynamicMatrix and a FixedMatrix. The DynamicMatrix would have a constructor that did

data = new T*[rows];
for (int i = 0; i < rows; i++)
{
    data[i] = new T[cols];
}
for (int i = 0; i < rows; i++)
{
    for (int j = 0; j < cols; j++)
    {
         data[i][j] = 0;
    }
}

And FixedMatrix just:

for (i=0; i < rows; i++)
{
    for (j=0; j < cols; j++)
    {
         data[i][j] = 0;    
    }
}

Creating a member variable T data; in the base class is easy enough. But then in the subclasses, how do I convert that to a double pointer? Perhaps I can't, I'm okay with that. But then what should I do instead?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

慕烟庭风 2024-10-23 11:41:18

在这里,您尝试使用继承来重用代码,在我看来,这不是一个好的设计方法;继承是为了实现自由,而组合是为了代码重用。

在这种情况下,如果确实有必要支持这些不同的情况,我将形式化一个二维数组:

template<typename T> class Array2D {
    public:
       virtual const T* operator[](int row_index) const = 0;
       virtual T* operator[](int row_index) = 0;
       virtual size_t rows() const = 0;
       virtual size_t cols() const = 0;
};

然后我将提供您指定的 Array2D 的实现:

template<typename T, int R, int C> class FixedArray2D : public Array2D {
     public:
       virtual const T* operator[](int row_index) const {
           return &data_[row_index][0];
       }
       virtual T* operator[](int row_index) {
            return &data_[row_index][0];
       }
       virtual size_t rows() const { return R; }
       virtual size_t cols() const { return C; }
     private:
        T data_[R][C];
};

template<typename T> class DynamicArray2D : public Array2D {
     public:
        DynamicAray2D(int rows, int cols) {
           // ...
        }
        // ...
};

此时,您可以实例化一个 Array2D代码> 使用任一格式。现在,无论您使用什么代码,只要需要处理此类对象,都可以简单地使用 const Array2D&Array2D&

也就是说,我认为这可能是不必要的复杂性,因为动态大小的数组适用于任何一种情况,因此我会选择这种方式,除非有令人信服的理由支持这两种类型。

Here you are trying to use inheritance for code reuse which, in my opinion, is not a good approach to design; inheritance is for freedom of implementation while composition is for code reuse.

In this case, if it were really necessary to support these different cases, I would formalize a 2d array:

template<typename T> class Array2D {
    public:
       virtual const T* operator[](int row_index) const = 0;
       virtual T* operator[](int row_index) = 0;
       virtual size_t rows() const = 0;
       virtual size_t cols() const = 0;
};

Then I would provide the implementations of Array2D that you've specified:

template<typename T, int R, int C> class FixedArray2D : public Array2D {
     public:
       virtual const T* operator[](int row_index) const {
           return &data_[row_index][0];
       }
       virtual T* operator[](int row_index) {
            return &data_[row_index][0];
       }
       virtual size_t rows() const { return R; }
       virtual size_t cols() const { return C; }
     private:
        T data_[R][C];
};

template<typename T> class DynamicArray2D : public Array2D {
     public:
        DynamicAray2D(int rows, int cols) {
           // ...
        }
        // ...
};

At this point, you can instantiate an Array2D using either format. Now whatever code you are using can simply take a const Array2D& or an Array2D& wherever it needs to deal with such an object.

That said, I think this is probably unnecessary complexity in that a dynamically sized array will work for either case, hence I would just go with that unless there were a compelling reason to support both types.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文