2010-10-04 2 views
2

эй, я получил то, что я не могу понять, есть два типа решений для перегрузки этого оператора. 1 включает в себя друга в начале метода, а другой 1 идет без друга. Мне очень понравилось бы, если бы некоторые объяснили, в чем разница между ними преимуществами/недостатками. , например, перегрузка оператора < < в классе рациональных:перегрузка оператора << в C++

class Rational: 
{ 
    private: int m_t,m_b; 
    ... 
    friend ostream& operator<<(ostream& out,const Rational& r) // option 1 
    { return out << r.m_t << "/" <<r.m_b;} // continue of option 1 

    ostream& operator<<(ostream& out,const Rational& r){return r.print();} // option 2 
    virtual ostream& print(ostream& out) const // continue of option 2 
    { // 
     return out<<m_t << "/" << m_b; 
    } // 
}; 

мне сказали, что второй вариант разве правильно, если some1 может исправить меня об этом я бы очень appriciate его. благодарит заранее.

+0

http://stackoverflow.com/questions/236801/should-operator-be-implemented-as-a-friend-or-as-a-member-function – DumbCoder

+0

http://stackoverflow.com/ вопросы/2458459/why-friend-function-is-preferred-to-member-function-for-operator – DumbCoder

+0

http://stackoverflow.com/questions/2828280/c-beginner-friend-functions-and-operator-overloading- что-есть-правильное/ – sbi

ответ

2

operator<< (for ostream) должен быть свободной функцией (поскольку левый аргумент представляет собой поток, а не ваш класс).

Ключевое слово friend делает его бесплатной функцией (свободной функцией, которая имеет доступ к частным членам).

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

class Rational: 
{ 
    private: int m_t,m_b; 
    public: 
    ... 
    virtual ostream& print(ostream& out) const 
    { 
     return out<<m_t << "/" << m_b; 
    } 
}; 

ostream& operator<<(ostream& out,const Rational& r) 
{ 
    return r.print(out); 
} 
4

Короткий ответ: Вариант № 2 фактически не является опцией, а синтаксической ошибкой, поскольку он пытается определить двоичный оператор как элемент, передающий два операнда.

Несколько более длинный ответ: если вы сделаете второй операнд свободной функцией (не членом класса), это будет работать. Какой из них предпочтительнее, зависит от обстоятельств и ваших предпочтений. Для начала: недостатком первого является то, что он позволяет operator<< получить доступ ко всему в Rational (включая частные вспомогательные функции), в то время как недостатком второго является то, что вы вводите функцию в общедоступный API класса, который никому не нужен.

+0

Есть ли способ исправить его, чтобы он работал? –

+0

Из того, что я слышал о другом в C++, он получил свои недостатки –

+0

и делает первый вариант с полиморфным? –

0

Рассмотрит функцию, которая должна вывести Num и вертеп Rational:

ostream& operator<<(ostream& out, const Rational& r) 
{ 
    return out; 
} 

К сожалению, это только глобальная функция. Как и любая другая глобальная функция, он не может получить доступ к частным членам Rational. Для того, чтобы заставить его работать с Rational объектами, вы должны сделать это friend из Rational:

class Rational 
{ 
    private: int m_t,m_b; 

    // ... 

    friend ostream& operator<<(ostream& out, const Rational& r); 
}; 

ostream& operator<<(ostream& out, const Rational& r) 
{ 
    out << r.m_t << "/" <<r.m_b; 
    return out; 
} 

friend ostream& operator<<(ostream& out, const Rational& r); внутри Rational класса указывает на то, что ostream& operator<<(ostream& out, const Rational& r) функция может непосредственно использовать Rational «s частных пользователей.

Теперь, когда вы пишете:

Rational r(1, 2); // Say, it sets num and den 
cout << r; 

следующий вызов функции производится:

operator<<(cout, r); 

Вы можете написать operator<< в качестве функции члена Rational? Это просто невозможно из-за вышеуказанного преобразования, где cout должен быть первым параметром. Если вы operator<< в качестве члена Rational:

class Rational 
{ 
    private: int m_t,m_b; 

    // ... 

    public: 

    ostream& operator<<(ostream& out) const 
    { 
     out << r.m_t << "/" <<r.m_b; 
     return out; 
    } 
}; 

Вы должны назвать это таким образом:

Rational r(1, 2); 
r.operator<<(cout); 

который некрасиво.

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