В чем причина отличного вывода от ожидаемого для программы на C ?

#c

#c

Вопрос:

Я наткнулся на программу, которая выдает результат, отличный от ожидаемого. В чем может быть причина?

Программа:

 #include <iostream>
using namespace std;

//Class A
class A
{
    int x,y;
    public:
    //constructor
    A(int X,int Y):x(X),y(Y)
    {
    }
    A SetX(int X)
    {
        x = X;
        return *this;
    }
    A SetY(int Y)
    {
        y=Y;
        return *this;
    }
    void print()
    {
        cout << x << " " << y;
    }
};
int main()
{
    A a(5, 5);
    a.SetX(10).SetY(20);//???
    a.print();

}
  

Как видно здесь, a создается со значением 5,5. затем вызываются SetX() и setY() со значениями 10 и 20 соответственно. Здесь я бы ожидал, что print() покажет вывод как 10, 20. Но, к удивлению, результат равен 10,5. То, что происходит, является фоном? Любая помощь приветствуется?

Комментарии:

1. Вы хотите возвращать ссылки в своих функциях установки: Aamp; SetY(int Y)

2. Это можно сделать для правильного вывода. Но знаете ли вы, в чем причина другого вывода здесь?

3. «Но знаете ли вы, в чем причина другого вывода здесь?» Потому что второй вызов setter будет применяться к другому (временному) экземпляру A , а не к исходному.

4. Почему и как здесь создается временный объект? Каковы условия для этого? Зависит ли это от компилятора или существуют предопределенные правила / условия, при которых будет создан временный объект?

5. Поймите, что C отличается от Java и C # и др. тем, что у вас могут быть объекты и ссылки на объекты, и вам нужно понимать разницу (указатели тоже). Знаете ли вы разницу между экземпляром объекта, ссылкой на экземпляр объекта и указателем на экземпляр объекта, а для полноты — указателем на ссылку на экземпляр объекта? Пожалуйста, скажите нам, понимаете ли вы эти концепции C , которые не все существуют в этих других языках.

Ответ №1:

Ваш A SetX(int X) возвращает копию объекта, поэтому, когда вы это делаете a.SetX(10).SetY(20); , .SetY он работает с этой копией, которая затем уничтожается.

Вы хотите изменить сигнатуру функции Aamp; SetX(int X); на, чтобы возвращать ссылку на исходный объект, а не на копию.

Комментарии:

1. Означает ли это, что здесь вызывается конструктор копирования по умолчанию при повторном выполнении * this ?

2. @santoshkumar — концептуально да. Но copy elision также и исследование.

3. Тогда каковы другие способы создания нового объекта? Если здесь применяется исключение копирования , то единственным вариантом создания временного объекта является только параметризованный конструктор . Это правильно?

4. Нет. Это намного сложнее.