C++构造函数、复制函数易错点

C++中复制函数在三种情况下自动调用:

  1. 用一个对象初始化另一个对象
  2. 函数的参数为对象
  3. 函数的返回值为对象

下面用几个代码片段解释复制函数的调用中的一些常见“坑”:

一:默认复制函数的自动调用

#include<iostream>
using namespace std;

class Point
{
public:
    Point(int X, int Y) :x(X), y(Y) {};
    void showCoordinate()
    {
        //展示坐标
        cout << "X=" << x << "\tY=" << y << endl;
    }
private:
    int x;
    int y;
};

int main()
{
    Point p1(0, 0);
    p1.showCoordinate();
    Point p2 = p1;          //此事并未编写显示的复制函数,系统会自动生成Point的一个自适应复制函数
    p2.showCoordinate();    //发现 p2 的坐标与 p1 相同
    cout << &p1 << endl;
    cout << &p2 << endl;    //显然,p2 只是 p1 复制函数之后的新的对象,在内存中的地址并不相同
    return 0;
}

二:不存在合适的构造函数【实质上还是复制函数的问题】

#include<iostream>
using namespace std;

class Point
{
public:
    Point(int X, int Y) :x(X), y(Y) {};
    Point(Point& p);
    int getX() { return x; }
    int getY() { return y; }
private:
    int x;
    int y;
};
Point::Point(Point& p) {
    x = p.x;
    y = p.y;
}
class Line
{
public:
    Line(Point temp_p1, Point temp_p2) {
        p1 = temp_p1;
        p2 = temp_p2;
    };
private:
    Point p1;
    Point p2;
};

int main()
{
    Point p1(0, 0);
    Point p2 = p1;        //此时复制函数仍然可以正常调用,但是 24 行报错
    /**
    * C2512“Point” : 没有合适的默认构造函数可用    
    * E0291    类 "Point" 不存在默认构造函数
    */
    
    return 0;
}

为什么出现这种情况,实质上是因为Line的构造函数中使用了无参数的构造函数,但是只有当没有编写构造函数时,系统会自动生成一个没有参数的构造函数,而编写了构造函数之后系统并不会自动生成

一个治标不治本的方法是,在class Point中加入一个无参数的构造函数。但是问题显而易见,么有参数的构造函数并么有实际意义。所以只能通过类的组合,将Point类内嵌在Line类中。

将其改为:

Line(Point temp_p1, temp_p2) :p1(temp_p1), p2(temp_p2);

至此,可以编写计算线段长度的程序:

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

class Point
{
public:
    Point(int X, int Y) :x(X), y(Y) {};
    Point(Point& p);
    int getX() { return x; }
    int getY() { return y; }
private:
    int x;
    int y;
};
Point::Point(Point& p) {
    x = p.x;
    y = p.y;
}
class Line
{
public:
    Line(Point temp_p1, Point temp_p2) : p1(temp_p1), p2(temp_p2) {};
    double getLen();
private:
    Point p1;
    Point p2;
};

//计算线段长度,比较简单,可以设置为内联
inline double Line::getLen()
{
    int a = abs(p1.getX() - p2.getX());
    int b = abs(p1.getY() - p2.getY());
    double len = sqrt(a * a + b * b);
    return len;
}

int main()
{
    Point p1(0, 0);
    Point p2(3, 4);
    Line line1(p1, p2);
    cout << line1.getLen() << endl;    //输出线段长度


    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值