二维数组类

017:二维数组类

总时间限制: 

1000ms

内存限制: 

65536kB

描述

写一个二维数组类 Array2,使得下面程序的输出结果是:

0,1,2,3,

4,5,6,7,

8,9,10,11,

next

0,1,2,3,

4,5,6,7,

8,9,10,11,

程序:

#include <iostream>
#include <cstring>
using namespace std;

class Array2 {
    //在此补充你的代码.
};

int main() {
    Array2 a(3,4);
    int i,j;
    for(  i = 0;i < 3; ++i )
        for(  j = 0; j < 4; j ++ )
            a[i][j] = i * 4 + j;
    for(  i = 0;i < 3; ++i ) {
        for(  j = 0; j < 4; j ++ ) {
            cout << a(i,j) << ",";
        }
        cout << endl;
    }
    cout << "next" << endl;
    Array2 b;     b = a;
    for(  i = 0;i < 3; ++i ) {
        for(  j = 0; j < 4; j ++ ) {
            cout << b[i][j] << ",";
        }
        cout << endl;
    }
    return 0;
}

输入

输出

0,1,2,3,
4,5,6,7,
8,9,10,11,
next
0,1,2,3,
4,5,6,7,
8,9,10,11,

样例输入

None

样例输出

0,1,2,3,
4,5,6,7,
8,9,10,11,
next
0,1,2,3,
4,5,6,7,
8,9,10,11,

这题没有get到点的话还挺麻烦的。关键在于做一个数组指针的指针。

分析:

1Array2 a(3,4); //构造函数,两int型参数,Array2是二维数组形式。

2a[i][j] = i * 4 + j;    //a[i][j] 在C++里相当于:a,operator[](i).operator[](j)

      但是用上面说的数组指针的指针则不用这么麻烦,只需重载 “ [ ] ” 即可,详见code。

3cout << a(i,j) << ",";   //重载"()",常规操作。

4 b = a;   //重载 "=",实现深拷贝。

5 这题不用重载流输入符,因为在 cout<< 这边的都不是类成员变量,是一些类成员函数,在类成员函数里返回能输出的标准值即可。

6常规的复制构造函数(这题用不上,也写写,练手嘛)和析构函数。

完整代码如下:

#include <iostream>
#include <cstring>
using namespace std;
 
class Array2 {
// 在此处补充你的代码
private:
    int ** p;//数组指针的指针,关键!
    int col,row;
public:
    //构造函数
    Array2(int x = 0, int y = 0):col(x),row(y){
        if( x && y == 0 ) p = NULL;
        else{
            p = new int*[col];
            for(int i = 0; i < col; i++){
                p[i] = new int[row];
            }
        }
    }
    //复制构造函数
    Array2(const Array2 & array2_){
        col = array2_.col;
        row = array2_.row;
        p = new int*[col];
        for(int i = 0; i < col; i++){
            p[i] = new int[row];
        }
        memcpy(p,array2_.p,sizeof(int) * col * row);
    }
 
    //重载"="实现深拷贝
    Array2 & operator=(const Array2 & array2_){
        if(p) delete []p;
        col = array2_.col;
        row = array2_.row;
        p = new int*[col];
        for(int i = 0; i < col; i++){
            p[i] = new int[row];
        }
        memcpy(p,array2_.p,sizeof(int) * col * row);
        return *this;
    }
 
    //析构函数
    ~Array2(){
        if(p) delete []p;
    }
 
    //重载"[]"
    int * operator[](int i){
        return p[i];
        //重载的是 a[][]的第一个[] ,因为返回的是p[x],则第二个[]相当于取p[x]的第y个。
    }
 
    //重载"()"
    int & operator()(int x, int y){ //重载()
        return p[x][y];
    }
 
};
 
int main() {
    Array2 a(3,4); //构造函数,两int型参数,Array2是二维数组形式。
    int i,j;
    for(  i = 0;i < 3; ++i )
        for(  j = 0; j < 4; j ++ )
            a[i][j] = i * 4 + j;
            //a[i][j] 在C++里相当于:a,operator[](i).operator[](j)
    for(  i = 0;i < 3; ++i ) {
        for(  j = 0; j < 4; j ++ ) {
            cout << a(i,j) << ","; //重载"()"
        }
        cout << endl;
    }
    cout << "next" << endl;
    Array2 b;
    b = a; //重载 "=",实现深拷贝。
    for(  i = 0;i < 3; ++i ) {
        for(  j = 0; j < 4; j ++ ) {
            cout << b[i][j] << ",";
        }
        cout << endl;
    }
    return 0;
}

  这就是我们今天讲的题,有关运算符重载!

如果大家不了解的话,可以看看下面这个:

运算符重载的注意事项:

  1. C++不允许程序员定义新的运算符(废话嘛,运算符已经够多了,还闲不够多吗?不够乱吗?)

  2. 重载过后的运算符应该符合日常的习惯:什么是日常习惯呢?举几个例子:complex_a+complex_b(我们重载的是加法这个运算符,但是函数里面写的是减法的运算,这就有点儿太坑人了)word_a>word_b(这个重载的是大于号,但是你判断写的是小于) 

  3. C++里面写运算符重载的时候不能改变运算符计算的优先级

  4. 还有一些运算符是不能进行重载的,哪些呢:".",".*","::","?:","sizeof"这些都不能进行重载.

  5. 重载某些运算符的时候,运算符重载函数必须生命为类的成员函数:(),[],->或者赋值运算符=号.

  6. 运算符重载的实质是将运算符重载为一个函数,使用运算符的表达式就被解释为对“运算符函数”的调用。

  7. 运算符可以被重载为全局函数,也可以被重载为成员函数。一般来说,倾向于将运算符重载为成员函数,这样能够较好地体现运算符和类的关系。

  8. 运算符被重载为全局函数时,函数参数的个数就是运算符的操作数个数,运算符的操作数就成为函数的实参。

  9. 运算符被重载为成员函数时,函数参数的个数就是运算符的操作数个数减一,运算符的操作数有一个成为函数作用的对象,其余的成为函数的实参。

  10. 必要时需要重载赋值运算符 “=” ,即进行深拷贝,以避免两个对象内部的指针指向同一片存储空间。

  11. 类型的名字可以作为强制类型转换运算符,也可以被重载为类的成员函数。它能使得对象被自动转换为某种类型。

  12. 重载运算符时,应该尽量保留运算符原本的用法和特性。例如重载 “+” 运算符,完成的功能就应该类似于做加法,如果在其中做减法就是不合适的;再例如,赋值运算符 “=” ,它是可以连用的,这个特性在重载后也应该保持,所以 operator= 函数一般需要返回其所作用对象的引用,以保持 “=” 连用的这个特性。

  13. 运算符重载函数不能有默认的参数,否则就改变了运算符操作数的个数,这显然是错误的

  14. 将运算符重载函数作为类的成员函数时,二元运算符的参数只有一个,一元运算符不需要参数。之所以少一个参数,是因为这个参数是隐含的

  15. 除了‘=’运算符以外,其他的运算符重载最好设计成为友元函数。

  16. 把‘=’运算符重载为类成员变量,并且将返回值设计成为该类的引用。

  17. 一定要自定义一个拷贝构造函数,这样在重载运算符返回对象副本的时候,编译器会自动调用拷贝构造函数,否则会出现结果错误。

  18. 友元关系不会被派生类继承。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙星尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值