我有一个用构造函数定义的结构:
struct Point {
double x; double y;
Point (double xx=0, double yy=0): x(xx),y(yy){};
};
我可以创建像这样的点,这很好用,
Point P0(0,0), P1(1,1);
但我希望能够修改它:
P0 = (4,5); //no compilation error but garbage returned when printing P0
不起作用!
另外,我有一个像我这样使用的功能
void Foo(Point P0, Point P1){
...do stuff
}
我希望像下面这样传递以下参数:
Foo((1,2),(2,3)); //no compilation error but garbage returned
我试着把这一切看起来并不是很清楚..任何帮助
答案 0 :(得分:3)
P0 = (4,5);
这不符合你的想法。
表达式(4,5)
的计算结果为5
。这是因为它包含所谓的逗号运算符。逗号运算符首先计算其左操作数,抛弃结果,然后计算其第二个操作数。所以这句话实际上等同于
P0 = 5;
现在,此相当于
P0 = Point(5);
相当于
P0 = Point(5, 0);
因为你有一个默认参数。它根本不是垃圾。它的定义非常明确。
在你的另一个陈述中恰好会发生同样的事情:
Foo((1,2),(2,3)); // same as Foo(Point(2, 0), Point(3, 0));
要解决此问题,您可以明确构建点:
P0 = Point(4, 5);
Foo(Point(1, 2), Point(2, 3));
或者,如果你有C ++ 11支持,你可以这样做:
P0 = {4, 5};
Foo({1, 2}, {2, 3});
(当大括号内出现逗号时,它的不是逗号运算符。它分隔初始化列表的元素。)
答案 1 :(得分:2)
(4,5)
等同于5
,因为这就是逗号运算符的工作方式:它计算第一个表达式,丢弃结果,然后计算第二个表达式。如果启用警告,您应该收到有关丢弃表达式的编译警告,没有副作用。
在C ++ 11中,您可以使用列表初始化器来执行您想要的操作:
P0 = {4,5};
Foo({1,2},{2,3});
如果你坚持使用较旧的方言,你必须拼写出来:
P0 = Point(4,5);
Foo(Point(1,2), Point(2,3));
答案 2 :(得分:2)
在本声明中
P0 = (4,5); //no compilation error but garbage returned when printing P0
表达式(4,5)
是带有comme运算符的表达式。它的值是第二个子表达式,即5。
然后编译器尝试将值5转换为Point类型的对象,以将其分配给P0。因为你有转换构造函数
Point (double xx=0, double yy=0): x(xx),y(yy){};
然后编译器使用参数5和0调用它,即Point( 5, 0 )
。此临时对象分配给P0。
您应该使用支撑初始化列表而不是逗号运算符。例如
P0 = { 4, 5 };
前提是您的编译器支持C ++ 11的此功能。 否则,您必须在表达式
的右侧明确指定构造函数P0 = Point( 4, 5 );
答案 3 :(得分:1)
您应该使用P0 = Point(4,5)代替。 Point(4,5)调用创建一个临时对象,然后将其复制到P0(实际上它通常是优化的,因此不需要实际复制)。