关于C++语言程序设计例6—18中的&,即Point &element(int index){ return points [index]; }

书上代码

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

class Point{
public: 
    Point():x(0),y(0){
        cout<<"Default Constructor called"<<endl;
    }
    Point(int x, int y):x(x), y(y){
        cout<<"Constructor called"<<endl; 
    }
    ~Point(){
        cout<<"Destructor called"<<endl;
    }
    int getX() const{return x;}
    int getY() const{return y;}
    void move(int newx,int newy){
        x = newx;
        y = newy;
    }
private:
    int x,y;
};
class ArrayOfPoints{
public:
    ArrayOfPoints(int size):size(size){
        points = new Point[size];
    }
    ~ArrayOfPoints(){
        cout<<"Deleting......";
        delete []points;
    }
    Point element(int index){
        assert(index >= 0 && index < size);
        return points[index];
    }
private:
    Point *points;
    int size;
};
int main()
{
        int num;
        cout<<"请输入要动态创建的个数:"<<endl;
        cin>>num;
        ArrayOfPoint Point(num);
        Point.Element(0).Move(5,4);
        Point.Element(1).Move(65,99);
        return 0;
}

其中Point & element(int)中的&让人很是费解
首先复习一下&(引用)的作用,是按照地址返回值,这是一个类似指针但又不同于指针的的操作,指针返回的是地址,它返回的是值,但说类似是因为它所返回的值是实实在在的原地址的那个值,而不是从那个值复制而来的另一个不同地址但却相等的另一个值。
这样我们可以改写一下代码

#include<iostream>
#include<cassert>
#include<cstdlib>
using namespace std;
class Point{
public: 
    Point():x(0),y(0){
        cout<<"Default Constructor called"<<endl;
    }
    Point(int x, int y):x(x), y(y){
        cout<<"Constructor called"<<endl; 
    }
    Point(Point &point):x(point.x), y(point.y){
        cout<<"is cpoying"<<endl;
    }
    ~Point(){
        cout<<"Destructor called"<<endl;
    }
    int getX() const{return x;}
    int getY() const{return y;}
    void move(int newx,int newy){
        x = newx;
        y = newy;
    }
private:
    int x,y;
};
class ArrayOfPoints{
public:
    ArrayOfPoints(int size):size(size){
        points = new Point[size];
    }
    ~ArrayOfPoints(){
        cout<<"Deleting......";
        delete []points;
    }
    Point element(int index){
        assert(index >= 0 && index < size);
        return points[index];
    }
private:
    Point *points;
    int size;
};
int main(){
    int count;
    count = 2;
    ArrayOfPoints pointsArray1(count);
    pointsArray1.element(0).move(5,10);
    pointsArray1.element(1).move(15,20);
    cout<<pointsArray1.element(0).getX()<<" "<<pointsArray1.element(0).getY()<<endl;
    cout<<pointsArray1.element(1).getX()<<" "<<pointsArray1.element(0).getY()<<endl;
    system("pause");
    return 0;
}

代码在原有基础上新加入了复制构造函数,并且执行复制构造函数时会输出is copying,并且我们还会新输出move后的x,y的值。
先执行一次加上&的版本

Default Constructor called
Default Constructor called
5 10
15 10
Press any key to continue . . .

我们可以发现,和初始代码结果差不多(只增加了move后俩点的坐标,(5,10)和(15,10),并且符合我们的认知)。

我们再执行一次去掉&后的版本`

Default Constructor called
Default Constructor called
is cpoying
Destructor called
is cpoying
Destructor called
is cpoying
0 is cpoying
0
Destructor called
Destructor called
is cpoying
0 is cpoying
0
Destructor called
Destructor called
Press any key to continue . . .

很明显,这次多了几句is copying(执行复制构造函数)和Destructor called(执行析构函数)。并且move后的俩点的坐标均是(0,0),即默认创建Point对象的初始值(不信你可以换着试试)

再让我们来分析分析原因:
这涉及函数的相关知识,函数再返回一个值的时候(假设此值与地址无关,即不是地址,指针,引用),那么会生成一个副本,让这个副本临时存储函数执行的结果,然后再将这个副本复制给相关变量,所以,无&的时候就会多执行复制构造函数,析构函数(删除副本)。这就是会出现如此多的复制构造函数和析构函数的原因。并且无法使用move对Point[index]造成影响,因为你move的只是副本传出的值而非原始地址的那个值,故你再次使用Point elment(int)函数时,他会重新生成副本Point,且这个Point的x,y均为0。

加上&后就可以避免以上问题了。

改版后的代码无&会在三处造成影响,1:执行Point elment(int)时,2:执行move()时,3:执行getX()时,(执行getY()时用的是执行getX()的那个Point,故不造成影响)。

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值