Kaip tinkamai perkrauti srauto operatorių?

Aš rašau mažą matricos biblioteką C ++ matricos operacijoms. Tačiau mano kompiliatorius skundžiasi, kur jis nebuvo anksčiau. Šis kodas liko lentynoje 6 mėnesius, o tarp manęs atnaujinau kompiuterį nuo debian etch iki lenny (g ++ (Debian 4.3.2-1.1) 4.3.2), tačiau turiu tą pačią problemą Ubuntu sistemoje su tuo pačiu g ++.

Čia yra atitinkama mano matricos klasės dalis:

 namespace Math { class Matrix { public: [...] friend std::ostream operator<< (std::ostream stream, const Matrix matrix); } } 

Ir „įgyvendinimas“:

 using namespace Math; std::ostream Matrix::operator <<(std::ostream stream, const Matrix matrix) { [...] } 

Tai kompiliatoriaus klaida:

matrix.cpp: 459: klaida: „std :: ostream Math :: Matrix :: Operatorius <(standartinis :: ostream const Math :: Matrix turėtų būti visiškai vienas argumentas

Aš šiek tiek supainiuosi dėl šios klaidos, bet vėl, mano „C + +“ po kelių „Java“ per 6 mėnesius gavo šiek tiek rūdžių.: -)

198
24 янв. nustatė Matthias van der Vlies sausio 24 d 2009-01-24 19:34 '09 19:34 2009-01-24 19:34
šaltinis
@ 5 atsakymai

Jūs nurodėte savo funkciją kaip friend . Tai nėra klasės narys. Iš įgyvendinimo turite pašalinti „ Matrix:: . friend reiškia, kad nurodyta funkcija (kuri nėra klasės narė) gali pasiekti privačių narių kintamuosius. Kaip įgyvendinate šią funkciją, panašus į „ Matrix klasės egzemplioriaus metodą, kuris yra neteisingas.

111
24 янв. Mehrdad Afshari atsakymas dėl sausio 24 d 2009-01-24 19:37 '09, 19:37 PM 2009-01-24 19:37
šaltinis

Papasakokite apie kitą galimybę: norėčiau naudoti draugų apibrėžimus:

 namespace Math { class Matrix { public: [...] friend std::ostream operator<< (std::ostream stream, const Matrix matrix) { [...] } }; } 

Ši funkcija automatiškai nukreipia aplinkinę Math vardų erdvę (net jei jos apibrėžtis yra šios klasės ribose), tačiau nebus matoma, nebent skambinate << su Matricos objektu, kuris sukels argumentą, priklausantį nuo šio operatoriaus apibrėžimo. Kartais tai gali padėti su dviprasmiškais skambučiais, nes jis yra nematomas kitiems argumentams nei Matrix. Rašydami savo apibrėžimą, taip pat galite tiesiogiai nurodyti vardus, apibrėžtus matricoje ir matricoje, nenurodydami pavadinimo su tam tikrais ilgais priešdėliais ir pateikdami šablonų parametrus, pvz., Math::Matrix<TypeA, N> .

128
25 янв. Johannes Schaub - litb atsakymas, sausio 25 d 2009-01-25 01:28 '09 ne 1:28 2009-01-25 01:28
šaltinis

Jei norite pridėti atsakymą į Mehrdadą,

 namespace Math { class Matrix { public: [...] } std::ostream operator<< (std::ostream stream, const Math::Matrix matrix); } 

Įgyvendindami

 std::ostream operator<<(std::ostream stream, const Math::Matrix matrix) { matrix.print(stream); //assuming you define print for matrix return stream; } 
69
24 янв. atsakymas pateikiamas kal 24 jan. 2009-01-24 21:51 '09 at 9:51 PM 2009-01-24 21:51
šaltinis

Darant prielaidą, kad kalbame apie operator << perkrovimą visoms klasėms, gautoms iš std::ostream Matrix klasės apdorojimui (o ne Matrix klasės perkrovimui), prasminga deklaruoti perkrovos funkciją ant matematikos vardų srities antraštėje.

Naudokite draugo funkciją tik tuo atveju, jei funkcijų negalima pasiekti per viešąsias sąsajas.

Matrix.h

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

Atkreipkite dėmesį, kad operatoriaus perkrova yra paskelbta už vardų srities ribų.

Matrix.cpp

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

Kita vertus, jei reikia atlikti perkrovos funkciją, draugas turi prieigą prie uždarų ir saugomų narių.

Math.h

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

Vietoj using namespace Math; turite pridėti funkcijų apibrėžtį vardų bloke 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; } } 
56
10 февр. Atsakymas duotas sanjivr 10 vasario mėn. 2012-02-10 19:09 2012 m. Liepos 12 d. 19:12 19:09
šaltinis

C ++ 14 galite naudoti šį šabloną, kad išspausdintumėte bet kurį objektą, turintį T :: print (std :: ostream const; narys

 template<class T> auto operator<<(std::ostream os, const T t) -> decltype(t.print(os), os) { t.print(os); return os; } 
29
05 марта '16 в 11:24 2016-03-05 11:24 atsakymas pateikiamas QuentinUK kovo 05 '16, 11:24 2016-03-05 11:24
šaltinis