C++类的组合的构造函数问题

为什么构建Line的时候要4次拷贝构造函数point,另外为什么拷贝构造line2的时候,又要调用2次point的拷贝构造函数。
Line::Line(Point xp1,Point xp2):p1(xp1),p2(xp2){}
这种写法是组合类的拷贝构造特有的么,这是什么意思,特别是后面的p1(xp1),p2(xp2)。

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

class Point
{
public:
     Point(int xx=0,int yy=0)
    {
          X=xx; Y=yy;
          cout<<"Point构造函数被调用"<<endl;
    }
     Point(Point &p);//拷贝函数
     int GetX() { return X; }
     int GetY() { return Y; }
private:
     int X,Y;
};

Point::Point(Point &p)//拷贝构造函数的实现
{
    X=p.X;
    Y=p.Y;
    cout<<"Point拷贝构造函数被调用!"<<endl;
}
//类的组合
class Line
{
public:
      Line(Point xp1,Point xp2);//构造函数
      Line(Line &);//拷贝函数
      double GetLen() { return len; }
private:
      Point p1,p2;
      double len;
};
//组合类的构造函数
Line::Line(Point xp1,Point xp2):p1(xp1),p2(xp2)
{
    cout<<"Line构造函数被调用"<<endl;
    double x=double(p1.GetX()-p2.GetX());
    double y=double(p1.GetY()-p2.GetY());
    len=sqrt(x*x+y*y);
}

//组合类的拷贝构造函数
Line::Line(Line &L):p1(L.p1),p2(L.p2)
{
    cout<<"Line拷贝构造函数被调用"<<endl;
    len=L.len;
}

int main()
{
    Point myp1(1,1);
    Point myp2(4,5);//建立Point类的对象
    Line line(myp1,myp2);
    Line line2(line);
    cout<<"The length of the line is:";
    cout<<line.GetLen()<<endl;
    cout<<"The length of the line2 is:";
    cout<<line2.GetLen()<<endl;
    return 0;
}

# Line::Line(Point xp1,Point xp2):p1(xp1),p2(xp2){}//解释4次的原因:

# 首先这个方法是Line的构造函数,它有2个参数,类型为Point,(注意:不是引用(Point&),也不是指针(Point*))

# 其次,冒号后面的叫构造函数的初始化列表,用于初始化成员变量

# 知道这两点之后,那么再来说原因:

# c++这门语言不像java,如果参数不写成引用(Point&)或者指针(Point*),那么再传递参数的时候会建立一个对象的副本。

# 再来看看这个Line::Line(Point xp1,Point xp2):p1(xp1),p2(xp2){},传入xp1时,会去创建一个Point的对象,调用1次Point的拷贝构造,

这是第1次,同理xp2,再进行p1(xp1)时,这又会调用1次Point的拷贝构造,同理p2(xp2),因此共4次
一般来说这个方法最好这么写Line::Line(const Point& xp1,const &Point xp2):p1(xp1),p2(xp2){},这样就只会调2次了

图片说明

冒号,初始话列表方式初始化变量。

Line::Line(Point xp1,Point xp2):p1(xp1),p2(xp2){}//解释4次的原因:

首先这个方法是Line的构造函数,它有2个参数,类型为Point,(注意:不是引用(Point&),也不是指针(Point*))

其次,冒号后面的叫构造函数的初始化列表,用于初始化成员变量,注意是初始化

知道这两点之后,那么再来说原因:

c++这门语言不像java,如果参数不写成引用(Point&)或者指针(Point*),那么在传递参数的时候会建立一个对象的副本。

再来看看这个Line::Line(Point xp1,Point xp2):p1(xp1),p2(xp2){},传入xp1时,会去创建一个Point的对象,调用1次Point的拷贝构造,这是第1次,同理xp2,再进行p1(xp1)时,这叫初始化p1,不是定义之后再赋值!这又会调用1次Point的拷贝构造,同理p2(xp2),因此共4次

一般来说这个方法最好这么写Line::Line(const Point& xp1,const Point& xp2):p1(xp1),p2(xp2){},这样就只会调2次了