在C++中分配结构

Assigning a struct in C++

本文关键字:结构 分配 C++      更新时间:2023-10-16

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

    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

我试图查找所有这些对我来说不太清楚.. 任何帮助

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});

(当逗号出现在大括号内时,它不是逗号运算符。它分隔初始值设定项列表的元素。

(4,5)相当于

5,因为这就是逗号运算符的工作方式:它计算第一个表达式,丢弃结果,然后计算第二个表达式。如果启用警告,则应收到有关没有副作用的丢弃表达式的编译警告。

在 C++11 中,您可以使用列表初始化器执行所需的操作:

P0 = {4,5};
Foo({1,2},{2,3});

如果你坚持使用较旧的方言,你必须把它拼出来:

P0 = Point(4,5);
Foo(Point(1,2), Point(2,3));

在此语句中

P0 = (4,5); //no compilation error but garbage returned when printing P0

表达式 (4,5) 是带有逗号运算符的表达式。其值是第二个子表达式 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 );

你应该改用 P0 = Point(4, 5)。Point(4, 5) 调用创建一个临时对象,然后将其复制到 P0(实际上它通常是优化的,因此不需要实际复制)。