Frage

Ich bin eine kleine Matrix-Bibliothek in C ++ für Matrix-Operationen zu schreiben. Doch mein Compiler beschwert, wo, bevor er tat es nicht. Dieser Code wurde für 6 Monate auf einem Regal links und dazwischen ich meinen Computer von Debian Etch aktualisiert lenny (g ++ (Debian 4.3.2-1.1) 4.3.2 aber) ich habe das gleiche Problem auf einem Ubuntu-System mit dem gleichen g ++.

Hier ist der relevante Teil meiner Matrix-Klasse:

namespace Math
{
    class Matrix
    {
    public:

        [...]

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

Und die "Umsetzung":

using namespace Math;

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

    [...]

}

Dies ist der Fehler vom Compiler gegeben:

  

matrix.cpp: 459: Fehler: ‚std :: ostream &   Math :: Matrix :: operator << (std :: ostream &,   const Math :: Matrix &)‘muss nehmen   genau ein Argument

Ich bin ein bisschen von diesem Fehler verwirrt, aber dann wieder mein C ++ ein bisschen rostig nachdem ich viele Java diese 6 Monate bekommen hat. : -)

War es hilfreich?

Lösung

Sie haben Ihre Funktion als friend erklärt. Es ist kein Mitglied der Klasse. Sie sollten Matrix:: aus der Umsetzung entfernen. friend bedeutet, dass die spezifizierte Funktion (der kein Mitglied der Klasse ist) private Elementvariablen zugreifen. Die Art und Weise Sie die Funktion implementiert ist wie eine Instanzmethode für Matrix Klasse, die falsch ist.

Andere Tipps

Nur du über eine andere Möglichkeit zu sagen: Ich mag mit Freund Definitionen dafür:

namespace Math
{
    class Matrix
    {
    public:

        [...]

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

Die Funktion automatisch in die umgebenden Namespace Math gezielt wird (auch wenn seine Definition im Rahmen dieser Klasse erscheint), aber nicht sichtbar sein, wenn Sie Operator rufen << mit einem Matrix-Objekt, die Lookup-abhängiges Argumente, wird feststellen, dass Operator Definition. Das kann manchmal mit mehrdeutigen Anrufen helfen, da es für Argumente andere Typen als Matrix unsichtbar ist. Wenn seine Definition schreiben, können Sie auch in Matrix definierten direkt auf Namen beziehen und mich in einer Matrix, ohne mit einigem möglicherweise langen Präfix den Namen der Qualifikation und Template-Parameter wie Math::Matrix<TypeA, N> bereitstellt.

Hinzufügen zu Mehrdad Antwort,

namespace Math
{
    class Matrix
    {
       public:

       [...]


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

In Ihrer Implementierung

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

Unter der Annahme, dass wir reden über operator << für alle Klassen, die von std::ostream Überlastung der Matrix Klasse (und nicht zu überlasten << für Matrix Klasse) zu handhaben, ist es sinnvoller, die Überlastfunktion außerhalb des Math-Namensraumes im Header zu erklären.

Verwenden Sie einen Freund Funktion nur, wenn die Funktionalität nicht über die öffentlichen Schnittstellen erreicht werden.

Matrix.h

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

Beachten Sie, dass der Betreiber Überlastung außerhalb des Namensraum deklariert.

Matrix.cpp

using namespace Math;
using namespace std;

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

Auf der anderen Seite, wenn Sie Ihre Überlastfunktion funktioniert brauche einen Freund gemacht werden heißt Zugriff auf private und geschützte Mitglieder benötigt.

math.h

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

Sie müssen die Funktionsdefinition mit einem Namespace-Block statt nur using namespace Math; einzuschließen.

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;
    }                 
}

In C ++ 14 können Sie die folgende Vorlage verwenden ein beliebiges Objekt zu drucken, die ein T :: Druck hat (std :: ostream &) const; Mitglied.

template<class T>
auto operator<<(std::ostream& os, const T& t) -> decltype(t.print(os), os) 
{ 
    t.print(os); 
    return os; 
} 
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top