2009-06-25 4 views
3

Я не уверен, еслиИспользует * это хорошая идея?

return *this 

это единственный способ, которым мы могли бы вернуть экземпляр класса, который называется функцией члена? Причина, по которой я спросил, заключается в том, что наш инструктор сказал нам избегать использования указателей, если это необходимо, и мне интересно, является ли это случаем, когда единственный способ сделать это - вернуть этот указатель.

Я работаю с классом дробей, который содержит численные числители и знаменатели частных данных. Функция-член, я говорю о том, используется для добавления двух фракций, например:

Fraction C = A.plus(B); 

плюс член функция определяется следующим образом:

Fraction& plus(const Fraction frac) 

инструктор хочет, чтобы сделать C = A + = B, поэтому я думаю, именно поэтому.

+13

Получить новый инструктор. – 2009-06-25 00:36:42

+1

Предполагается ли плюс изменить A в вашем примере? Если нет, вы должны возвращать новый объект Fraction, который является суммой A и B. –

ответ

7

Получите нового инструктора. Похоже, что объявление плюса() полностью неверно.

  • это, вероятно, должен возвращать значение, а не ссылку
  • , если он должен возвращать ссылку, он должен возвращать константную ссылку
  • он должен обязательно принять константную ссылку в качестве параметра

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

+0

Вы читаете мой ум в своем первом пункте: D – AraK

+0

Я думаю, что это скорее плохой студент, неправильно копирующий вопрос, плохой учитель. Я бы сказал, предпочитает ссылку на указатель. И возврат возвращает ссылку, а не указатель, проверенный учителем. –

+0

Объявление в порядке, если вы считаете, что 'plus' соответствует' operator + = ', и вы ожидаете, что передача по значению будет быстрее, чем передача по ссылке. (Я не удивлюсь, если это так) –

1

Да, это единственный способ. С помощью этого можно обращаться только к текущему объекту в методе, и это указатель.

Это хорошо, и это принятая практика.

1

Нет ничего плохого в возвращении *this. Например, как предполагается, должны работать перегрузки модифицирующих операторов. Кажется, что метод plus - это просто способ предоставить оператор + = для вашего класса, фактически не перегружая оператора (я полагаю, вы еще не дошли до перегрузки оператора), поэтому возвращение *this в этом случае является обычным поведением.

0

В вашем методе plus() вы, вероятно, должны создать новый объект Fraction и вернуть его вместо того, чтобы изменять текущий, а затем возвращать *this. Вероятно, вы не хотите менять A в A.plus(B). Чтобы вернуть новый Fraction, подпись plus() бы лучше быть:

Fraction plus(const Fraction &frac); 

(В случае, если вы не в настоящее время модифицирующим this в методе plus(), почему вы хотите вернуть *this?)

2

I думаю, что в этом случае можно безопасно использовать

return *this 

потому что this относится к текущему объекту, так что гарантируется существование, поэтому он не будет нулевым ,

Причина plus возвращает ссылку на себя так, что он может быть прикован:

Fraction C = A.plus(B).plus(D) // perhaps? 

Обратите внимание, что в приведенном выше случае C будет создан путем копирования результата сложения. Это также предполагает, что операция plus предназначена для изменения объекта (в данном случае A) и возврата ссылки на этот модифицированный объект.

Не мог бы согласиться с ссылкой вместо того, чтобы сделать копию параметра?

Fraction& plus(const Fraction& frac) 

Это аналогично тому, как вы бы реализовать operator= (пример):

A& operator=(const A& right) { 
    if(this == &right) return *this; // Handle self-assignment 
    b = right.b; 
    return *this; 
    } 

Может быть, вы хотели бы, чтобы не изменять объект и вернуть новый объект:

// assuming there's a constructor Fraction(int numerator, int denominator): 
Fraction* plus(Fraction const& rhs) 
{ 
    return new Fraction(numerator * rhs.denominator 
         + rhs.numerator * denominator, 
         denominator * rhs.denominator); 
} 

Но это конечно, должен возвращать указатель на новый экземпляр, который не является ссылкой, как может потребоваться в вашей задаче (?).

Или еще лучше:

Fraction plus(Fraction const& rhs) 
{ 
    return Fraction(numerator * rhs.denominator 
        + rhs.numerator * denominator, 
        denominator * rhs.denominator); 
} 

Это позволит создать фракцию в пространстве вызова функции, так что нет накладных копирования структуры по возвращению.

+0

Фактически, это не гарантируется, что оно не равно null. Вызов метода на объекте NULL приведет к сбою, когда это будет разыменовано. – Michael

+0

Но в этом случае вы столкнулись бы с сбоем при попытке вызвать плюс на NULL, а не внутри, плюс при попытке вернуть * это я предполагаю – stefanB

+0

. Если бы функция была виртуальной, вы только потерпели бы крах, так как она попыталась бы получить доступ к виртуальные таблицы. В противном случае это похоже на вызов функции, не являющейся членом, с недопустимым параметром. – Michael

0

Я считаю, что семантика должна состоять в том, что функция-член «плюс» возвращает «новый» объект, который представляет собой сумму вызывающего и вызываемого. примечания :: новое не означает «новое» ключевое слово в C++ :) так для примера,

// the constructor accepts (numerator, denominator). 
// in your case, the caller object would be A, and the called object would be B(other). 
return Fraction(numerator * other.denominator + other.numerator * denominator, denominator * other.denominator); 

Единственное место, где я вижу, что правильно возвращать ссылку на это при перегрузке операторов, которые имеют сторону последствия.

Чтобы уточнить больше, это должно быть вашим «плюс» подпись,

Fraction plus(const Fraction& frac); 

ни абонент, ни вызываемый должен осуществляться «плюс».

0

наш инструктор сказал нам, чтобы избежать использования указателей при необходимости

Вы фактически вернув значение разыменования указателя, а не указатель. Поэтому ты должен быть хорошим.

Лично я никогда не называл методы или обращался к членам через this. То есть, я НЕ сделать следующее:

class A { 
    public: 
    int x; 
    int get_x() 
    { 
     return this->x; 
    } 

    int get_x_plus_5() 
    { 
     return this->get_x() + 5; 
    } 
} 

Однако я прекрасно с возвращением *this.

Ваш инструктор, вероятно, пытается избежать (1) возврата указателей к объектам в стеке из функций (что означает, что они не будут существовать после выхода функции) и (2) выделения объектов в свободном хранилище когда вам это не нужно. this не страдает ни одной из этих проблем.

Смежные вопросы