#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. Нет. Это намного сложнее.