Хорошо, Таким образом, я погуглил эту проблему, и я искал переполнение стека, но я, может казаться, не нахожу хороший ответ. Так, я задаю вопрос по здесь, который конкретен к моей проблеме. Если это - легкий ответ, хороши, я плохо знаком с языком. Вот моя проблема:
Я пытаюсь записать метод для класса C++, который перегружает оператор. Я хочу возвратить копию измененного экземпляра, но не самого экземпляра. Для простоты примера я буду использовать a BigInt
класс для демонстрации проблемы, которую я имею.
Если у меня был следующий код:
const BigInt & operator+() const //returns a positive of the number
{
BigInt returnValue = *this; //this is where I THINK the problem is
returnValue.makepositve(); //for examples sake
return returnValue;
}
Я получаю ошибку, что возвращаемое значение, возможно, было создано на стеке. Я знаю, что это означает, что я должен создать объект на "куче" и возвратить ссылку. Но Если я должен был изменить 3-ю строку на что-то как:
BigInt & returnValue = *this;
Я получаю ошибку при сообщении мне, что синтаксис не является правильным. Я не действительно уверен, что сделать, любая справка очень ценится!
Проблема в сигнатуре вашей функции. Вам действительно нужно вернуть весь объект, а не только ссылку.
Ваша функция будет выглядеть так
BigInt operator+() const //returns a positive of the number
{
BigInt returnValue = *this;
returnValue.makepositve(); //for examples sake
return returnValue;
}
Вы также можете сделать возвращаемое значение оператора BigInt
. Тогда конструктор копирования автоматически сработает при возврате:
const BigInt operator+() const //returns a positive of the number
{
BigInt returnValue = *this; //this is where I THINK the problem is
returnValue.makepositve(); //for examples sake
return returnValue;
}
Теперь похоже, что конструктор копирования произойдет дважды, один раз внутри оператора, а другой - при возврате функции, но с оптимизацией возвращаемого значения это фактически произойдет только один раз, поэтому с точки зрения производительности это настолько хорошо, насколько это возможно.
Обратите внимание, что перегруженные операторы должны иметь интуитивно понятную семантику. Определение унарного +
для обозначения «абсолютного значения», как вы это делаете в приведенном примере кода, чрезвычайно сбивает клиентов с толку. Операторы для пользовательских типов должны вести себя так же, как для встроенных типов. Например, + (- 5)
дает -5, а не +5. Таким образом, ваша реализация оператора +
должна выглядеть так:
BigInt& operator+() //returns the unchanged number
{
return *this;
}
const BigInt& operator+() const //returns the unchanged number
{
return *this;
}
Если вы хотите предоставить функцию абсолютного значения, сделайте это:
BigInt abs(BigInt x)
{
x.makePositive();
return x;
}
Мой C ++ немного устарел, но как насчет:
BigInt* returnValue = new BigInt(this)
...
return *returnValue;