在C ++中分配结构

时间:2014-02-24 00:15:05

标签: c++

我有一个用构造函数定义的结构:

    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

我试着把这一切看起来并不是很清楚..任何帮助

4 个答案:

答案 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(实际上它通常是优化的,因此不需要实际复制)。