读书人

初学者提问函数参数调用拷贝构造函数

发布时间: 2012-02-26 20:19:44 作者: rapoo

菜鸟提问,函数参数调用拷贝构造函数的问题?????
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


拷贝构造函数CPoint(Cpint&)被调用,(20,50)
拷贝构造函数CPoint(Cpint&)被调用,(12,15)
拷贝构造函数CPoint(Cpint&)被调用,(20,50)
拷贝构造函数CPoint(Cpint&)被调用,(12,15)
构造函数CLine(CPoint,CPoint)被调用(12,15)-(20,50)

所以得出结论传实参的时候是由右到左的,构造形参当然也就由右到左了
但初始化成员的时候与初始化表顺序无关,与生命成员的顺序有关

读书人网 >C++

热点推荐