Kefirek Temat założony przez niniejszego użytkownika |
C++ przeciążenie operatora<< klasy » 2018-07-18 11:12:57 Witam Klasa Magazyn zawiera składową prywatną Towar *ctowar(wskaźnik do klasy Towar). Klasa Towar posiada zaprzyjaźnioną funkcję przeciążającą operator<< do przekazania swoich składowych do strumienia(patrz. poniżej kod klasy Towar.h, Towar.cpp) Klasa Magazyn posiada funkcję zaprzyjaźnioną przeciążającą operator<< do przekazania swoich składowych do strumienia(patrz. poniżej kod klasy Magazyn.h, Magazyn.cpp). W ciele funkcji wyrażenie magazyn.GetTowar() : QDataStream & operator <<( QDataStream & out, const Magazyn & magazyn ) { out << magazyn.GetNazwa() << magazyn.GetTowar(); return out; }
powoduje błąd przy próbie zapisu danych do pliku. Mógłbym zapisać magazyn.GetTowar().GetGoodsCateory() << itd następne składowe i to działa. Moje pytanie dlaczego nie zadziała ...<< magazyn.GetTowar(); z powyższej funkcji skoro W klasie Towar jest zdefiniowany operator<< ??? : QDataStream & operator <<( QDataStream & out, const Towar & towar ) { out << towar.cGoodsCategory << towar.cGoodsSubCategory << towar.cProducer << towar.cGoodsUse << towar.cTradeName << towar.cPrice << towar.cCurrency << towar.cUnitQuantities << towar.GetGabaryt(); return out; }
i wie jak przekazać składowe klasy Towar do strumienia. Jak uniknąć ponownego wypisywania wszystkich składowych w funkcji: QDataStream & operator <<( QDataStream & out, const Magazyn & magazyn ) { out << magazyn.GetNazwa() << magazyn.GetTowar().GetGoodsCategory() return out; }
Klasa Magazyn.h############################################################ #ifndef MAGAZYN_H #define MAGAZYN_H
#include <QString> #include "domlibcore_global.h" #include <Towar.h> #include <QVector>
class Towar;
class DOMLIBCORESHARED_EXPORT Magazyn { public: Magazyn( QString nazwaMagazyn, Towar * towar ); Magazyn(); virtual ~Magazyn(); void SetNazwa( QString nazwaMagazyn ); void SetTowar( Towar * towar ); QString GetNazwa() const; Towar & GetTowar() const; friend QDataStream & operator <<( QDataStream & out, const Magazyn & magazyn ); friend QDataStream & operator >>( QDataStream & in, Magazyn & magazyn ); private: QString cNazwaMagazyn; Towar * cTowar; };
#endif
Klasa Magazyn.cpp############################################################ #include "magazyn.h"
Magazyn::Magazyn( QString nazwaMagazyn, Towar * towar ) : cNazwaMagazyn( nazwaMagazyn ) , cTowar( towar ) { }
Magazyn::Magazyn() { }
Magazyn::~Magazyn() { }
void Magazyn::SetNazwa( QString nazwaMagazyn ) { cNazwaMagazyn = nazwaMagazyn; }
void Magazyn::SetTowar( Towar * towar ) { cTowar = towar; }
QString Magazyn::GetNazwa() const { return cNazwaMagazyn; }
Towar & Magazyn::GetTowar() const { return * cTowar; }
QDataStream & operator <<( QDataStream & out, const Magazyn & magazyn ) { out << magazyn.GetNazwa() << magazyn.GetTowar(); return out; } QDataStream & operator >>( QDataStream & in, Magazyn & magazyn ) { in >> magazyn.cNazwaMagazyn >> magazyn.GetTowar(); return in; }
Klasa Towar.h############################################################ #ifndef TOWAR_H #define TOWAR_H
#include <QString> #include <QDate> #include <gabaryt.h> #include "domlibcore_global.h"
class Gabaryt;
class DOMLIBCORESHARED_EXPORT Towar { public: Towar( QString goodsCategory, QString goodsSubCategory, QString producer, QString goodsUse, QString tradeName, double prise, int quantity, double vlaue, QString currency, QString unitQuantities, Gabaryt * gabaryt ); Towar(); virtual ~Towar(); void SetGoodsCategory( QString goodsCategory ); void SetGoodsSubCategory( QString goodsSubCategory ); void SetProducer( QString producer ); void SetGoodsUse( QString goodsUse ); void SetTradeName( QString tradeName ); void SetPrise( double prise ); void SetQuantity( int quantity ); void SetCurrency( QString currency ); void SetUnitQuantities( QString unitQuantities ); QString GetGoodsCategory() const; QString GetGoodsSubCategory() const; QString GetProducer() const; QString GetGoodsUse() const; QString GetTradeName() const; double GetPrise() const; int GetQuantity() const; double GetValue() const; QString GetCurrency() const; QString GetUnitQuantities() const; Gabaryt & GetGabaryt() const; private: QString cGoodsCategory; QString cGoodsSubCategory; QString cProducer; QString cGoodsUse; QString cTradeName; double cPrice; int cQuantity; double Cvalue; QString cCurrency; QString cUnitQuantities; Gabaryt * cGabaryt; };
#endif
Klasa Towar.cpp############################################################ #include "towar.h"
Towar::Towar( QString goodsCategory, QString goodsSubCategory, QString producer, QString goodsUse, QString tradeName, double prise, int quantity, double value, QString currency, QString unitQuantities, Gabaryt * gabaryt ) : cGoodsCategory( goodsCategory ) , cGoodsSubCategory( goodsSubCategory ) , cProducer( producer ) , cGoodsUse( goodsUse ) , cTradeName( tradeName ) , cPrice( prise ) , cQuantity( quantity ) , Cvalue( value ) , cCurrency( currency ) , cUnitQuantities( unitQuantities ) , cGabaryt( gabaryt ) { } Towar::Towar() { }
Towar::~Towar() { }
void Towar::SetGoodsCategory( QString goodsCategory ) { cGoodsCategory = goodsCategory; }
void Towar::SetGoodsSubCategory( QString goodsSubCategory ) { cGoodsSubCategory = goodsSubCategory; }
void Towar::SetProducer( QString producer ) { cProducer = producer; }
void Towar::SetGoodsUse( QString goodsUse ) { cGoodsUse = goodsUse; }
void Towar::SetTradeName( QString tradeName ) { cTradeName = tradeName; }
void Towar::SetPrise( double prise ) { cPrice = prise; }
void Towar::SetQuantity( int quantity ) { cQuantity = quantity; }
void Towar::SetCurrency( QString currency ) { cCurrency = currency; }
void Towar::SetUnitQuantities( QString unitQuantities ) { cUnitQuantities = unitQuantities; }
QString Towar::GetGoodsCategory() const { return cGoodsCategory; }
QString Towar::GetGoodsSubCategory() const { return cGoodsSubCategory; }
QString Towar::GetProducer() const { return cProducer; }
QString Towar::GetGoodsUse() const { return cGoodsUse; }
QString Towar::GetTradeName() const { return cTradeName; }
double Towar::GetPrise() const { return cPrice; }
int Towar::GetQuantity() const { return cQuantity; }
double Towar::GetValue() const { return cQuantity * cPrice; }
QString Towar::GetCurrency() const { return cCurrency; }
QString Towar::GetUnitQuantities() const { return cUnitQuantities; }
Gabaryt & Towar::GetGabaryt() const { return * cGabaryt; }
QDataStream & operator <<( QDataStream & out, const Towar & towar ) { out << towar.cGoodsCategory << towar.cGoodsSubCategory << towar.cProducer << towar.cGoodsUse << towar.cTradeName << towar.cPrice << towar.cCurrency << towar.cUnitQuantities << towar.GetGabaryt(); return out; } QDataStream & operator >>( QDataStream & in, Towar & towar ) { in >> towar.cGoodsCategory >> towar.cGoodsSubCategory >> towar.cProducer >> towar.cGoodsUse >> towar.cTradeName >> towar.cPrice >> towar.cCurrency >> towar.cUnitQuantities >> towar.GetGabaryt(); return in; }
Pozdrawiam |
|
pekfos |
» 2018-07-18 13:18:36 Jaki błąd? |
|
Kefirek Temat założony przez niniejszego użytkownika |
Odp » 2018-07-18 15:25:09 Program przerywał działanie po próbie zapisu danych klas do pliku binarnego: program nieoczekiwanie przerwał działanie. Poniżej funkcja zapisująca dane klas do pliku binarnego: bool MagazynDao::CreateMagazyn( Magazyn & magazyn ) { CreateMagazynDirectory(); QString fileName = magazyn.GetNazwa() + ".mag"; QFile file( "./Magazins/" + fileName ); if( !file.open( QIODevice::WriteOnly | QIODevice::Append ) ) return false; QDataStream out( & file ); out.setVersion( QDataStream::Qt_5_10 ); out << magazyn; file.close(); return true; }
Poniżej funkcja inicjacyjna danych składowych klas - już poprawiona druga wersja z którą program działa prawidłowo: QStringListModel & MagazynModel::CreateMagazyn() { cListaMagazyn.append( cModelName ); cListModelMagazyn->setStringList( cListaMagazyn ); qDebug() << cListaMagazyn.size() << " - Model name: " << cModelName; Gabaryt * gabaryt = new Gabaryt( 5, 6, 6, "ddd", "m" ); Towar * towar = new Towar( "d", "c", "S", "e", "d", 5, 5, 6, "p", "d", gabaryt ); Magazyn * magazyn = new Magazyn( cModelName, towar ); qDebug() << "True or False: " << magazynDao.CreateMagazyn( * magazyn ); return * cListModelMagazyn; }
Wcześniej wyglądało to tak - wersja z którą program kończył nieoczekiwanie działanie: QStringListModel & MagazynModel::CreateMagazyn() { cListaMagazyn.append( cModelName ); cListModelMagazyn->setStringList( cListaMagazyn ); qDebug() << cListaMagazyn.size() << " - Model name: " << cModelName; Gabaryt * gabaryt = new Gabaryt(); gabaryt->SetLenght(); Towar * towar = new Towar(); towar->SetGoodsUse(); towar->SetGabaryt( gabaryt ); Magazyn * magazyn = new Magazyn(); magazyn->SetNazwe(); magazyn->SetTowar( towar ); qDebug() << "True or False: " << magazynDao.CreateMagazyn( * magazyn ); return * cListModelMagazyn;
Czyli wywołanie konstruktorów bezparametrowych dla poszczególnych klas i ustawienie składowych klas Setter'ami Nie wiadomo dlaczego nie mogłem wywołać konstruktora bezparametrowego dla klasy Gabaryt. Po jego wykomentowaniu udało się zapisać do pliku jedynie nazwę magazynu: magazyn->SetNazwe(cMagazynName); bład: call of overloaded 'Gabaryt()' is ambiguous. Klasa Gabaryt poniżej: Klasa Gabaryt.h ifndef GABARYT_H #define GABARYT_H
#include <QString> #include "domlibcore_global.h" #include <QDataStream>
class DOMLIBCORESHARED_EXPORT Gabaryt { public: Gabaryt( double width = 0, double height = 0, double depth = 0, QString volumeUnit = "m3", QString linearUnit = "m" ); Gabaryt(); virtual ~Gabaryt(); void SetWidth( double width ); void SetHeight( double height ); void SetDepht( double depth ); void SetVolumeUnit( QString volumeUnit ); void SetLinearUnit( QString linearUnit ); double GetWidth() const; double GetHeight() const; double GetDepth() const; QString GetVolumeUnit() const; QString GetLinearUnit() const; double GetVolume() const; friend QDataStream & operator <<( QDataStream & out, const Gabaryt & gabaryt ); friend QDataStream & operator >>( QDataStream & in, Gabaryt & gabaryt ); private: double cWidth; double cHeight; double cDepth; double cVolume; QString cVolumeUnit; QString cLienarUnit; };
#endif
Klasa Gabaryt.cpp #include "gabaryt.h" #include <cstring>
Gabaryt::Gabaryt( double width, double height, double depth, QString volumeUnit, QString linearUnit ) : cWidth( width ) , cHeight( height ) , cDepth( depth ) , cVolumeUnit( volumeUnit ) , cLienarUnit( linearUnit ) { }
Gabaryt::Gabaryt() { }
Gabaryt::~Gabaryt() { }
void Gabaryt::SetWidth( double width ) { cWidth = width; }
void Gabaryt::SetHeight( double height ) { cHeight = height; }
void Gabaryt::SetDepht( double depth ) { cDepth = depth; }
void Gabaryt::SetVolumeUnit( QString volumeUnit ) { cVolumeUnit = volumeUnit; }
void Gabaryt::SetLinearUnit( QString linearUnit ) { cLienarUnit = linearUnit; }
double Gabaryt::GetWidth() const { return cWidth; }
double Gabaryt::GetHeight() const { return cHeight; }
double Gabaryt::GetDepth() const { return cDepth; }
QString Gabaryt::GetVolumeUnit() const { return cVolumeUnit; }
QString Gabaryt::GetLinearUnit() const { return cLienarUnit; }
double Gabaryt::GetVolume() const { return cWidth * cHeight * cDepth; }
QDataStream & operator <<( QDataStream & out, const Gabaryt & gabaryt ) { out << gabaryt.cWidth << gabaryt.cHeight << gabaryt.cDepth << gabaryt.cVolumeUnit << gabaryt.cLienarUnit; return out; } QDataStream & operator >>( QDataStream & in, Gabaryt & gabaryt ) { in >> gabaryt.cWidth >> gabaryt.cHeight >> gabaryt.cDepth >> gabaryt.cVolumeUnit >> gabaryt.cLienarUnit; return in; }
Wyglada to tak jakby tylko wywołanie konstruktorów z parametrami było prawidłowe, a wywołanie konstruktorów bezparametrowych i następnie ustawianie składowych klas settr'ami nie było w tym wypadku prawidłowe?????? O co chodzi????? |
|
Kefirek Temat założony przez niniejszego użytkownika |
cd... » 2018-07-18 17:04:19 Po pozbyciu się parametrów domyślnych w konstruktorze Klasy Gabaryt: Było: Gabaryt::Gabaryt( double width = 0, double height = 0, double depth = 0, QString volumeUnit = "mm3", QString linearUnit = "mm" ) : cWidth( width ) , cHeight( height ) , cDepth( depth ) , cVolumeUnit( volumeUnit ) , cLienarUnit( linearUnit ) { }
Jest: Gabaryt::Gabaryt( double width, double height, double depth, QString volumeUnit, QString linearUnit ) : cWidth( width ) , cHeight( height ) , cDepth( depth ) , cVolumeUnit( volumeUnit ) , cLienarUnit( linearUnit ) { }
...nie wywala już błedu przy wywoływaniu konstruktora bezparametrowego klasy Gabaryt() Gabaryt *gabaryt = new Gabaryt() - teraz ok i wszystko się kompiluje i prawidłowo zapisuje do pliku korzystając z konstruktorów domyślnych jak poniżej: QStringListModel & MagazynModel::CreateMagazyn() { cListaMagazyn.append( cModelName ); cListModelMagazyn->setStringList( cListaMagazyn ); Gabaryt * gab = new Gabaryt(); gab->SetDepht( 5 ); gab->SetHeight( 5 ); gab->SetLinearUnit( "mm" ); gab->SetVolumeUnit( "mm3" ); gab->SetWidth( 6 ); Towar * towar = new Towar(); towar->SetCurrency( "pln" ); towar->SetGabaryt( gab ); towar->SetGoodsCategory( "kk" ); towar->SetGoodsSubCategory( "k" ); towar->SetGoodsUse( "kk" ); towar->SetPrise( 5 ); towar->SetProducer( "kk" ); towar->SetQuantity( 3 ); towar->SetTradeName( "ds" ); towar->SetUnitQuantities( "kl" ); towar->SetValue( 5 ); Magazyn * magazyn = new Magazyn(); magazyn->SetNazwa( cModelName ); magazyn->SetTowar( towar ); qDebug() << "True or False: " << magazynDao.CreateMagazyn( * magazyn ); }
Ciekawe dlaczego parametry domyślne w konstruktorze z parametrami powodowało nie możliwość użycia konstruktora bezparametrowego klasy Gabaryt????????? |
|
j23 |
» 2018-07-18 20:03:10 Metoda Magazyn::GetTowar nie powinna zwracać referencji, jeśli jest możliwość ustawienia cTowar na nullptr. W domyślnym konstruktorze klasy Magazyn powinieneś ustawić cTowar na jakąś konkretną wartość.
|
|
Kefirek Temat założony przez niniejszego użytkownika |
cd... » 2018-07-18 20:47:32 Zgadzam się co do zwracanej referencji - moje przeoczenie :-) poprawione: Towar Magazyn::GetTowar() const { return * cTowar; }
Mogę ustawić cTowar w Magazyn.h private:
QString cNazwaMagazyn; Towar * cTowar = nullptr;
[cyt] W domyślnym konstruktorze klasy Magazyn powinieneś ustawić cTowar na jakąś konkretną wartość. [/cyt] Magazyn::Magazyn() { cTowar->cCurrency = "pln"; cTowar->cGoodsCategory = "Budowlane"; cTowar->cGabaryt = ???? }
|
|
pekfos |
» 2018-07-18 20:49:47 To nie jest poprawione. Magazyn::Magazyn() { cTowar->cCurrency = "pln"; cTowar->cGoodsCategory = "Budowlane"; cTowar->cGabaryt = ???? } |
A to są bzdury. Miałeś nadać jakąś wartość cTowar, czyli wskaźnikowi. Zamiast tego próbujesz duplikować funkcjonalność konstruktora Towar. Jeśli cTowar jest wskaźnikiem z jakiegoś powodu (innego niż 'bo tak ci się napisało'), to albo gwarantuj, że wskazuje na coś z sensem, albo uwzględniaj możliwość, że nie wskazuje na nic. |
|
Kefirek Temat założony przez niniejszego użytkownika |
cd... » 2018-07-18 21:13:40 Zmieniłem wartość zwracaną z referencji Gabaryt & Towar::GetGabaryt() const;
Gabaryt Towar::GetGabaryt() const;
ale wywala błąd: :160: błąd: no match for 'operator>>' (operand types are 'QDataStream' and 'Gabaryt') >> towar.cUnitQuantities >> towar.GetGabaryt(); ^ błąd: invalid initialization of non-const reference of type 'Gabaryt&' from an rvalue of type 'Gabaryt' >> towar.cUnitQuantities >> towar.GetGabaryt(); ^ Ciekawe , że po analogicznej zmianie dla Klasy Magazyn powyższy błąd nie występuje. Kod klas pisałem dość dawno, i przypominam sobie, że właśnie miałem problem z tym błędem i dlatego zwracałem przez referencje i wtedy kod się prawidłowo kompilował.???? |
|
« 1 » 2 |