Назначение структуры в C ++

0

У меня есть структура, определенная с помощью конструктора как такового:

    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 ответа

2
Лучший ответ

(4,5) эквивалентно только 5, так как то, как работает оператор запятой: он оценивает первое выражение, отбрасывает результат, затем оценивает второй. Вы должны получить предупреждение компиляции об отброшенном выражении без побочных эффектов, если вы включите предупреждения.

В С++ 11 вы можете использовать инициализатор списка, чтобы делать то, что вы хотите:

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

Если вы застряли со старым диалектом, вам нужно будет прописать его:

P0 = Point(4,5);
Foo(Point(1,2), Point(2,3));
  • 0
    Да .. строительство это хорошо. Как насчет изменения значений без необходимости проходить через все члены с оператором точки .. У меня нет C ++ 11
  • 0
    @ Программист: Я не знаю, что вы имеете в виду. Оператор точки - это то, как вы получаете доступ и изменяете члены класса как еще ты хочешь это сделать?
Показать ещё 1 комментарий
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));

или, если у вас есть поддержка С++ 11, вы можете сделать это:

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

(Когда запятая происходит внутри фигурных скобок, она не является оператором запятой. Она разделяет элементы списка инициализаторов.)

  • 1
    Как насчет перегрузки оператора скобок?
  • 0
    @ Гэт, ты шутишь? Скобки не могут быть перегружены.
Показать ещё 8 комментариев
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.

Вместо оператора запятой вам следует использовать список упрощенных init. Например

P0 = { 4, 5 };

при условии, что ваш компилятор поддерживает эту функцию C++ 11. В противном случае вам нужно явно указать конструктор в правой части выражения

P0 = Point( 4, 5 );
1

Вместо этого вы должны использовать P0 = Point (4, 5). Вызов Point (4, 5) создает временный объект, который затем копируется в P0 (на самом деле он обычно оптимизируется, поэтому фактическое копирование не требуется).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню