初学者提问,函数参数调用拷贝构造函数的有关问题?
菜鸟提问,函数参数调用拷贝构造函数的问题?????
class CPoint
{
protected:
int x,y;
public:
CPoint(int xx = 0,int yy = 0);
CPoint(CPoint &p);
void dispaly();
int getX();
int getY();
};
CPoint::CPoint(int xx,int yy)
{
x = xx;
y = yy;
printf( "构造函数CPoint(int int)被调用 ");
printf( "(%d,%d) ",x,y);
printf( "\r\n ");
}
CPoint::CPoint(CPoint & p)
{
x = p.x;
y = p.y;
printf( "拷贝构造函数CPoint(Cpint&)被调用, ");
printf( "(%d,%d) ",x,y);
printf( "\r\n ");
}
void CPoint::dispaly()
{
printf( "(%d,%d) ",x,y);
}
int CPoint::getX()
{
return x;
}
int CPoint::getY()
{
return y;
}
class CLine
{
private:
CPoint start;
CPoint end;
public:
CLine(int,int,int,int);
CLine(CPoint,CPoint);
};
CLine::CLine(int x1,int y1,int x2,int y2):start(x1,y1),end(x2,y2)
{
printf( "构造函数CLine(int,int,int,int)被调用 ");
start.dispaly();
printf( "- ");
end.dispaly();
printf( "\r\n ");
}
CLine::CLine(CPoint p1,CPoint p2):start(p1),end(p2)
{
printf( "构造函数CLine(CPoint,CPoint)被调用 ");
start.dispaly();
printf( "- ");
end.dispaly();
printf( "\r\n ");
}
int _tmain(int argc, _TCHAR* argv[])
{
CPoint p1(12,15),p2(20,50);
CLine line1(10,20,100,200),line2(p1,p2);
return 0;
}
输出结果:
构造函数CPoint(int int)被调用(12,15)
构造函数CPoint(int int)被调用(20,50)
构造函数CPoint(int int)被调用(10,20)
构造函数CPoint(int int)被调用(100,200)
构造函数CLine(int,int,int,int)被调用(10,20)-(100
拷贝构造函数CPoint(Cpint&)被调用,(20,50)
拷贝构造函数CPoint(Cpint&)被调用,(12,15)
拷贝构造函数CPoint(Cpint&)被调用,(12,15)
拷贝构造函数CPoint(Cpint&)被调用,(20,50)
构造函数CLine(CPoint,CPoint)被调用(12,15)-(20,50)
从结果来看,在将实参p1和p2传递给CLine的构造函数的形参时,先传递的右边的参数
为什么第二个参数的拷贝构造函数先调用呢???
------解决方案--------------------
C/C++中函数参数传递顺序是从右往左压栈的
不过函数参数计算的顺序在标准中是没有规定的,依赖编译器实现,比如说
int f() { return 1; }
int g() { return 2; }
void h(int a, int b) { ... };
h(f(),g());
到底先调用f(),还是先调用g()在C++标准中是没有规定的
------解决方案--------------------
拷贝构造函数CPoint(Cpint&)被调用,(20,50)
拷贝构造函数CPoint(Cpint&)被调用,(12,15)
====
这两个是按从右到左入栈顺序初始化
拷贝构造函数CPoint(Cpint&)被调用,(12,15)
拷贝构造函数CPoint(Cpint&)被调用,(20,50)
==
这两个是按CLine初始化列表顺序初始化
------解决方案--------------------
楼主的问题是不是有点问题呢
你的第二个参数是指右边还是左边啊
从结果看,我得出的问题是传参时是由右到左所以构造形参时
调用拷贝函数是由右到左, 但在初始化成员的时候则是由左到右
把 CLine::CLine(CPoint p1,CPoint p2):start(p1),end(p2)
改为CLine::CLine(CPoint p1,CPoint p2):end(p2),start(p1)
结果一样,MS初始化表无关
于是把
private:
CPoint start;
CPoint end;
改为:
private:
CPoint end;
CPoint start;
结果:
构造函数CPoint(int int)被调用(12,15)
构造函数CPoint(int int)被调用(20,50)
构造函数CPoint(int int)被调用(10,20)
构造函数CPoint(int int)被调用(100,200)
构造函数CLine(int,int,int,int)被调用(10,20)-(100
class CPoint
{
protected:
int x,y;
public:
CPoint(int xx = 0,int yy = 0);
CPoint(CPoint &p);
void dispaly();
int getX();
int getY();
};
CPoint::CPoint(int xx,int yy)
{
x = xx;
y = yy;
printf( "构造函数CPoint(int int)被调用 ");
printf( "(%d,%d) ",x,y);
printf( "\r\n ");
}
CPoint::CPoint(CPoint & p)
{
x = p.x;
y = p.y;
printf( "拷贝构造函数CPoint(Cpint&)被调用, ");
printf( "(%d,%d) ",x,y);
printf( "\r\n ");
}
void CPoint::dispaly()
{
printf( "(%d,%d) ",x,y);
}
int CPoint::getX()
{
return x;
}
int CPoint::getY()
{
return y;
}
class CLine
{
private:
CPoint start;
CPoint end;
public:
CLine(int,int,int,int);
CLine(CPoint,CPoint);
};
CLine::CLine(int x1,int y1,int x2,int y2):start(x1,y1),end(x2,y2)
{
printf( "构造函数CLine(int,int,int,int)被调用 ");
start.dispaly();
printf( "- ");
end.dispaly();
printf( "\r\n ");
}
CLine::CLine(CPoint p1,CPoint p2):start(p1),end(p2)
{
printf( "构造函数CLine(CPoint,CPoint)被调用 ");
start.dispaly();
printf( "- ");
end.dispaly();
printf( "\r\n ");
}
int _tmain(int argc, _TCHAR* argv[])
{
CPoint p1(12,15),p2(20,50);
CLine line1(10,20,100,200),line2(p1,p2);
return 0;
}
输出结果:
构造函数CPoint(int int)被调用(12,15)
构造函数CPoint(int int)被调用(20,50)
构造函数CPoint(int int)被调用(10,20)
构造函数CPoint(int int)被调用(100,200)
构造函数CLine(int,int,int,int)被调用(10,20)-(100
拷贝构造函数CPoint(Cpint&)被调用,(20,50)
拷贝构造函数CPoint(Cpint&)被调用,(12,15)
拷贝构造函数CPoint(Cpint&)被调用,(12,15)
拷贝构造函数CPoint(Cpint&)被调用,(20,50)
构造函数CLine(CPoint,CPoint)被调用(12,15)-(20,50)
从结果来看,在将实参p1和p2传递给CLine的构造函数的形参时,先传递的右边的参数
为什么第二个参数的拷贝构造函数先调用呢???
------解决方案--------------------
C/C++中函数参数传递顺序是从右往左压栈的
不过函数参数计算的顺序在标准中是没有规定的,依赖编译器实现,比如说
int f() { return 1; }
int g() { return 2; }
void h(int a, int b) { ... };
h(f(),g());
到底先调用f(),还是先调用g()在C++标准中是没有规定的
------解决方案--------------------
拷贝构造函数CPoint(Cpint&)被调用,(20,50)
拷贝构造函数CPoint(Cpint&)被调用,(12,15)
====
这两个是按从右到左入栈顺序初始化
拷贝构造函数CPoint(Cpint&)被调用,(12,15)
拷贝构造函数CPoint(Cpint&)被调用,(20,50)
==
这两个是按CLine初始化列表顺序初始化
------解决方案--------------------
楼主的问题是不是有点问题呢
你的第二个参数是指右边还是左边啊
从结果看,我得出的问题是传参时是由右到左所以构造形参时
调用拷贝函数是由右到左, 但在初始化成员的时候则是由左到右
把 CLine::CLine(CPoint p1,CPoint p2):start(p1),end(p2)
改为CLine::CLine(CPoint p1,CPoint p2):end(p2),start(p1)
结果一样,MS初始化表无关
于是把
private:
CPoint start;
CPoint end;
改为:
private:
CPoint end;
CPoint start;
结果:
构造函数CPoint(int int)被调用(12,15)
构造函数CPoint(int int)被调用(20,50)
构造函数CPoint(int int)被调用(10,20)
构造函数CPoint(int int)被调用(100,200)
构造函数CLine(int,int,int,int)被调用(10,20)-(100