标题:自定义C++二维数组雏形类
只看楼主
uouo99
Rank: 2
等 级:论坛游民
威 望:3
帖 子:30
专家分:98
注 册:2019-9-30
结帖率:50%
已结贴  问题点数:20 回复次数:4 
自定义C++二维数组雏形类

因为C++不直接支持二维数组,例如int a[8][10];是可以的,但是int dim1 = 8; int dim2 = 10; int a[dim1][dim2];却不可以,所以自定义了一个二维数组类,方便动态创建二维数组。
学习C++过程中参考某书学习并写下的一个二维数组雏形类,求bug修正和完善,谢谢。。。

程序代码:
#include <string>
#include <iostream>
using namespace std;


template<typename T>
class Array2D  //表示二维数组的类
{
public:
    class Array1D  //表示一维数组的类
    {
    public:
        T& operator[](int index)
        {
            return arr1[index];
        }
        const T& operator[](int index) const
        {
            return arr1[index];
        }
        T* CreateArr1D(int nums)
        {
            arr1 = new T[nums];
            return arr1;
        }
        ~Array1D()
        {
            delete[] arr1;
        }
        //...
    private:
        T* arr1 = nullptr;
    };
    Array2D(int dim1, int dim2)
    {
        arr2 = new Array1D[dim1];
        for (int i = 0; i < dim1; i++)
            arr2[i].CreateArr1D(dim2);   
    }
    Array1D& operator[](int index)
    {
        return arr2[index];
    }
    const Array1D& operator[](int index) const
    {
        return arr2[index];
    }
    ~Array2D()
    {
        delete[] arr2;
    }
    //...
private:
    Array1D* arr2;
};

//Test:
int main()
{
    Array2D<int> p(3,5);
    p[0][0] = 100;
    p[2][4] = 200;
    cout << p[0][0] << " " << p[2][4] << endl;   
}

搜索更多相关主题的帖子: C++ int return index 二维数组 
2019-10-07 10:03
uouo99
Rank: 2
等 级:论坛游民
威 望:3
帖 子:30
专家分:98
注 册:2019-9-30
得分:0 
自己先优化一下吧,抛砖引玉~
主要优化两点:
1.operator[]函数和const版本的代码重复,现通过cast转型将前者调用后者的代码。
2.将指向数组的裸指针替换为智能指针数组,因此析构函数也不需要有了
优化后代码如下:

程序代码:
#include <string>
#include <iostream>
#include <memory>
using namespace std;


template<typename T>
class Array2D  //表示二维数组的类
{
public:
    class Array1D  //表示一维数组的类
    {
    public:
        T& operator[](int index)
        {
            return const_cast<T&>(static_cast<const Array1D&>(*this)[index]);
        }
        const T& operator[](int index) const
        {
            return arr1[index];
        }
        auto& CreateArr1D(int nums)
        {
            arr1.reset(new T[nums]);
            return arr1;
        }
        //...
    private:
        unique_ptr<T[]> arr1{ nullptr };
    };
    Array2D(int dim1, int dim2)
    {
        arr2.reset(new Array1D[dim1]);
        for (int i = 0; i < dim1; i++)
            arr2[i].CreateArr1D(dim2);   

    }
    Array1D& operator[](int index)
    {
        return const_cast<Array1D&>(static_cast<const Array2D&>(*this)[index]);
    }
    const Array1D& operator[](int index) const
    {
        return arr2[index];
    }
    //...
private:
    unique_ptr<Array1D[]> arr2{ nullptr };
};

//Test:
int main()
{
    Array2D<int> p(3,5);
    p[0][0] = 100;
    p[2][4] = 200;
    cout << p[0][0] << " " << p[2][4] << endl;   

}


2019-10-07 11:29
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:20 
下标类型int是不对的,应该是size_t
默认生成的 拷贝构造 和 赋值 是浅拷贝
你这实现的不是二维数组,而是指针的一维数组,两者的内存布局不一样。
2019-10-07 12:12
uouo99
Rank: 2
等 级:论坛游民
威 望:3
帖 子:30
专家分:98
注 册:2019-9-30
得分:0 
以下是引用rjsp在2019-10-7 12:12:27的发言:

下标类型int是不对的,应该是size_t
默认生成的 拷贝构造 和 赋值 是浅拷贝
你这实现的不是二维数组,而是指针的一维数组,两者的内存布局不一样。

嗯,确实如你所说,不过你说的第三点内存布局的问题,不知道如何修改,C++实现二维数组的方式貌似本身就是使用一维数组来实现的(一维数组元素保存的又是另外一个数组),我这么做的主要目的也是想模仿这种设计,并且由于无法直接重载形如operator[][]的操作符,想让形如X[][]的形式能够模仿原始二维数组的方式一样去使用,所以定义了一个1维数组的类。
2019-10-07 13:06
uouo99
Rank: 2
等 级:论坛游民
威 望:3
帖 子:30
专家分:98
注 册:2019-9-30
得分:0 
根据rjsp大神的建议,程序做了以下修改:
1.修改int类型为size_t,作为数组下标更为合理。
2.由于C++内置数组类型不支持直接拷贝和赋值,所以在代码中将原来会自动生成的拷贝构造和拷贝赋值运算符函数删除掉。

优化后代码如下:
程序代码:
#include <string>
#include <iostream>
#include <memory>
using namespace std;


template<typename T>
class Array2D  //表示二维数组的类
{
public:
    class Array1D  //表示一维数组的类
    {
    public:
        Array1D() = default;
        T& operator[](size_t index)
        {
            return const_cast<T&>(static_cast<const Array1D&>(*this)[index]);
        }
        const T& operator[](size_t index) const
        {
            return arr1[index];
        }
        auto& CreateArr1D(size_t nums)
        {
            arr1.reset(new T[nums]);
            return arr1;
        }
        Array1D(const Array1D&) = delete;
        Array1D& operator=(const Array1D&) = delete;
        //...
    private:
        unique_ptr<T[]> arr1{ nullptr };
    };
    Array2D(size_t dim1, size_t dim2)
    {
        arr2.reset(new Array1D[dim1]);
        for (size_t i = 0; i < dim1; i++)
            arr2[i].CreateArr1D(dim2);   

    }
    Array1D& operator[](size_t index)
    {
        return const_cast<Array1D&>(static_cast<const Array2D&>(*this)[index]);
    }
    const Array1D& operator[](size_t index) const
    {
        return arr2[index];
    }
    Array2D(const Array2D&) = delete;
    Array2D& operator=(const Array2D&) = delete;
    //...
private:
    unique_ptr<Array1D[]> arr2{ nullptr };
};

//Test:
int main()
{
    Array2D<int> p(3,5);
    p[0][0] = 100;
    p[2][4] = 200;
    cout << p[0][0] << " " << p[2][4] << endl;   

}



[此贴子已经被作者于2019-10-7 17:02编辑过]

2019-10-07 13:30



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-497127-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.203787 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved