كيفية التحميل الزائد بشكل صحيح على عامل التشغيل << لـ ostream؟

StackOverflow https://stackoverflow.com/questions/476272

سؤال

أنا أكتب مكتبة مصفوفة صغيرة في C++ لعمليات المصفوفة.لكن المترجم الخاص بي يشكو، حيث لم يكن الأمر كذلك من قبل.تم ترك هذا الرمز على رف لمدة 6 أشهر ، وبين ما بين أنني قمت بترقية جهاز الكمبيوتر الخاص بي من Debian Etch إلى Lenny (G ++ (Debian 4.3.2-1.1) 4.3.2) ولكن لدي نفس المشكلة على نظام Ubuntu بنفس G ++ .

هنا هو الجزء ذو الصلة من فئة المصفوفة الخاصة بي:

namespace Math
{
    class Matrix
    {
    public:

        [...]

        friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix);
    }
}

و"التنفيذ":

using namespace Math;

std::ostream& Matrix::operator <<(std::ostream& stream, const Matrix& matrix) {

    [...]

}

وهذا هو الخطأ الذي قدمه المترجم:

ماتريكس.CPP:459:خطأ:"STD :: Ostream & Math :: Matrix :: Operator << (Std :: Ostream & ، const Math :: Matrix &)" يجب أن تأخذ حجة واحدة بالضبط

أنا في حيرة من أمري بسبب هذا الخطأ، ولكن مرة أخرى أصبح برنامج C++ الخاص بي صدئًا بعض الشيء بعد القيام بالكثير من Java خلال تلك الأشهر الستة.:-)

هل كانت مفيدة؟

المحلول

ولقد أعلن وظيفة الخاص بك كما friend. انها ليست عضوا في الطبقة. يجب إزالة Matrix:: من التنفيذ. friend يعني أن وظيفة معينة (وهي ليست عضوا في الطبقة) يمكن الوصول للمتغيرات الخاصة بالأعضاء الخاصة. الطريقة التي نفذت هي وظيفة مثل أسلوب مثيل لفئة Matrix الذي هو الخطأ.

نصائح أخرى

وفقط أقول لك عن واحد الاحتمال الآخر: أنا أحب استخدام تعريفات صديق لذلك:

namespace Math
{
    class Matrix
    {
    public:

        [...]

        friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix) {
            [...]
        }
    };
}

وسيتم استهدفت وظيفة تلقائيا إلى المحيطة Math مساحة الاسم (على الرغم من تعريفه يبدو في نطاق تلك الفئة) ولكن لن تكون مرئية إلا إذا كنت استدعاء المشغل << مع كائن مصفوفة الأمر الذي سيجعل حجة بحث يعتمد تجد أن تعريف المشغل. يمكن أن يساعد في بعض الأحيان مع دعوات غامضة، لأنه غير مرئي لأنواع حجة أخرى من مصفوفة. عند كتابة تعريفه، يمكنك أيضا الرجوع مباشرة إلى الأسماء المعرفة في مصفوفة وإلى Matrix نفسها، من دون تأهيل الاسم مع بعض بادئة ربما طويلة وتوفير المعلمات قالب مثل Math::Matrix<TypeA, N>.

لإضافة إلى مهرداد الجواب،

namespace Math
{
    class Matrix
    {
       public:

       [...]


    }   
    std::ostream& operator<< (std::ostream& stream, const Math::Matrix& matrix);
}

في التطبيق الخاص بك

std::ostream& operator<<(std::ostream& stream, 
                     const Math::Matrix& matrix) {
    matrix.print(stream); //assuming you define print for matrix 
    return stream;
 }

على افتراض أننا نتحدث عن التحميل الزائد operator << لجميع الفئات المستمدة من std::ostream للتعامل مع Matrix الطبقة (وليس التحميل الزائد << ل Matrix class)، فمن المنطقي الإعلان عن وظيفة التحميل الزائد خارج مساحة الاسم Math في الرأس.

استخدم وظيفة الصديق فقط إذا كان لا يمكن تحقيق الوظيفة عبر الواجهات العامة.

مصفوفة.ح

namespace Math { 
    class Matrix { 
        //...
    };  
}
std::ostream& operator<<(std::ostream&, const Math::Matrix&);

لاحظ أنه تم الإعلان عن التحميل الزائد للمشغل خارج مساحة الاسم.

Matrix.cpp

using namespace Math;
using namespace std;

ostream& operator<< (ostream& os, const Matrix& obj) {
    os << obj.getXYZ() << obj.getABC() << '\n';
    return os;
}

من ناحية أخرى، إذا كانت وظيفة التحميل الزائد لديك يفعل بحاجة إلى أن تكون صديقا أي.يحتاج إلى الوصول إلى الأعضاء الخاصين والمحميين.

الرياضيات.ح

namespace Math {
    class Matrix {
        public:
            friend std::ostream& operator<<(std::ostream&, const Matrix&);
    };
}

تحتاج إلى إحاطة تعريف الوظيفة بكتلة مساحة الاسم بدلاً من مجرد ذلك using namespace Math;.

Matrix.cpp

using namespace Math;
using namespace std;

namespace Math {
    ostream& operator<<(ostream& os, const Matrix& obj) {
        os << obj.XYZ << obj.ABC << '\n';
        return os;
    }                 
}

في C ++ 14 يمكنك استخدام القالب التالي لطباعة أي الكائن الذي لديه T :: طباعة CONST (الأمراض المنقولة جنسيا :: ostream و)؛ الأعضاء.

template<class T>
auto operator<<(std::ostream& os, const T& t) -> decltype(t.print(os), os) 
{ 
    t.print(os); 
    return os; 
} 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top