Eigener Datentyp int ab 1, (Bitshift, Konversion), limits(.h) mit C++98 und Linux
-
Einführung:
Um den Code intuitiver verstehbar zu machen und nicht bei jeder Variablen 1 oder 2 Byte zu verschwenden,
hätte ich gern hätte ich einen Datentyp unsigned short int und unsigned long int,
welcher die positiven ganzen Zahlen, also ohne die 0, beinhaltet.
Selbst wenn es geringfügig mehr Rechenaufwand bedeuten sollte.Das ursprünglich gedachte C++-Modell umgehe ich oft ungern,
da ich die aufblähung des Codes und somit wahrscheinlich auch des Programms
vermeiden und auch einen möglicht leicht nachvollziehbaren Quelltext schreiben möchte.
Daher definiere ich zunächst nur Opperatorfunktionen, welche ich brauche.Vorerst schließt dies beispielsweise globale Opperatorfunktionen,
zur Ermöglichung der Vertauschbarkeit von Opperanden aus.Falls es sich lohnt
kann ich zusätzlich zu den Konvertierenden Konstruktoren noch
sepatate Opperatorfunktionen für jeden gebrauchten Datentyp hinzufügen,
damit Laufzeit und der Speicherplatz
zur Erstellung von temporären Objekten gespart wird.Ich schreibe hier also nicht direkt eine universelle Klasse.
Wenn es soetwas allerdings schon gibt würde ich mich auf einen Hinweis freuen.Auf Exception-Handling verzichte ich in dem Beispiel. Dies aufgrund dem
erhöhten Laufzeitbedarf. Zudem soll das Programm in den meisten Fällen
auch bei zeitweiser Produktion von Datenmüll weiterlaufen.
Fehlermeldungen werden hier zur Sichtung auf der Konsole ausgegeben.Fehler:
Der Bitshift Operator "<<" produziert den Fehler:
[C++ Fehler] Unit1.cpp(8): E2094 'operator<<' ist im Typ 'ostream' für Argumente des Typs 'Spo' nicht implementiertBei Iteratorverwendung (im Test mit advance) gibt es den Fehler:
[C++ Fehler] _iterator_base.h(434): E2096 Ungültige Strukturoperation
Dies bezüglich _iterator_base.h der bei:
`if (__n > 0)while (__n--) ++__i;
else
while (__n++) --__i;
Wenn diesbezüglich die benutzerdefinierte Konversion
Spo::operator int() const` definiert ist, gibt es die Fehler:
[C++ Fehler] Unit1.cpp(17): E2015 Mehrdeutigkeit zwischen 'Spo::operator -(const Spo &) const' und 'Spo::operator int() const'
[C++ Fehler] Unit1.cpp(17): E2285 Keine Übereinstimmung für 'advance<_InputIterator,_Distance>Mit Linux g++ gibt es bei Verwendung von limits(.h) und C++98 den Fehler:
error: 'USHRT_MAX' was not declared in this scope
Die auf http://stackoverflow.com/questions/3233054/error-int32-max-was-not-declared-in-this-scope
zum Datentyp int32 vorgeschlagene Lösung der Einbindung von#define __STDC_LIMIT_MACROS
war ohne Wirkung.Ich würde mich freuen, wenn da jemand etwas wüsste.
Codebeispiel:
Unit1.cpp:
#pragma hdrstop // Wird mit Linux g++ ignoriert #include "Unit2.h" int main(int argc, char* argv[]) { list<bool> lst; lst.push_back(); lst.push_back(); list<bool>::iterator i=lst.begin(); ++i; Spo s1; s1=2; //int iii=s1; //cout << s1 << endl; // [C++ Fehler] Unit1.cpp(8): cout << USHRT_MAX << endl; // E2094 'operator<<' ist im Typ 'ostream' für Argumente des Typs 'Spo' nicht implementiert cout << s1.GetInt() << endl; s1.operator<<(cout); //advance(i, s1-1); // [C++ Fehler] _iterator_base.h(434): E2096 Ungültige Strukturoperation // bei: // if (__n > 0) // while (__n--) ++__i; // else // while (__n++) --__i; i=lst.begin(); advance(i, s1.GetInt()-1); cin.get(); // Dummyinput for keeping the console window open. return 0; }
Unit2.cpp:
#pragma hdrstop // Wird mit Linux g++ ignoriert #include "Unit2.h" #pragma package(smart_init) // Wird mit Linux g++ ignoriert Spo::Spo() { m_spo = new unsigned short int; } Spo::Spo(unsigned short int spo) { m_spo = new unsigned short int(spo-1); } Spo::~Spo() { delete m_spo; } Spo &Spo::operator=(const Spo &b) { *m_spo = *b.m_spo; return *this; } Spo &Spo::operator++() { if (*m_spo!=USI_MAX) ++*m_spo; else cout << "Fehler: Element vom Typ Spo hat bereits den höchsten Wert -> Nicht inkrementiert" << endl; return *this; } Spo &Spo::operator++(int praefix) { return ++*this; } Spo &Spo::operator--() { if (*m_spo!=USI_MIN) --*m_spo; else cout << "Fehler: Element vom Typ Spo hat bereits den niedrigsten Wert -> Nicht dekrementiert" << endl; return *this; } Spo &Spo::operator--(int praefix) { return --*this; } Spo Spo::operator+(const Spo &b) const { return Spo((*m_spo+1)+(*b.m_spo+1)); // m_spo has an offset of -1 } Spo Spo::operator-(const Spo &b) const { return Spo((*m_spo+1)-(*b.m_spo+1)); } Spo Spo::operator*(const Spo &b) const { return Spo((*m_spo+1)*(*b.m_spo+1)); } Spo Spo::operator/(const Spo &b) const { return Spo((*m_spo+1)/(*b.m_spo+1)); } bool Spo::operator==(const Spo &b) const { if (*m_spo==*b.m_spo) return true; else return false; } bool Spo::operator!=(const Spo &b) const { return !(*this==b); } bool Spo::operator<(const Spo &b) const { return *m_spo<*b.m_spo; } bool Spo::operator>(const Spo &b) const { return b<*this; } bool Spo::operator<=(const Spo &b) const { return !(*this>b); } bool Spo::operator>=(const Spo &b) const { return !(*this<b); } ostream &Spo::operator<<(ostream &os) const { return os << *m_spo+1; } int Spo::GetInt() const { return *m_spo+1; } //Spo::operator int() const // Bei advance: [C++ Fehler] Unit1.cpp(17): E2015 Mehrdeutigkeit zwischen 'Spo::operator -(const Spo &) const' und 'Spo::operator int() const' // { // [C++ Fehler] Unit1.cpp(17): E2285 Keine Übereinstimmung für 'advance<_InputIterator,_Distance>(_List_iterator<bool,_Nonconst_traits<bool> >,undefined)' gefunden // return *m_spo+1; // }
Unit2.h:
#ifndef Unit2H #define Unit2H #include <iostream> // Operator overloading, (cout) #define __STDC_LIMIT_MACROS // Empfehlung zur Problembehebung in Linux leider wirkungslos #include <limits> #include <list> using namespace std; const unsigned short int USI_MIN=0; // USI = unsigned short int const unsigned short int USI_MAX=USHRT_MAX; class Spo // ShortPos positive unsigned short int { unsigned short int* m_spo; public: Spo(); Spo(unsigned short int spo); ~Spo(); Spo &operator=(const Spo &b); Spo &operator++(); Spo &operator++(int praefix); Spo &operator--(); Spo &operator--(int praefix); Spo operator+(const Spo &b) const; Spo operator-(const Spo &b) const; Spo operator*(const Spo &b) const; Spo operator/(const Spo &b) const; bool operator==(const Spo &b) const; bool operator!=(const Spo &b) const; bool operator<(const Spo &b) const; bool operator>(const Spo &b) const; bool operator<=(const Spo &b) const; bool operator>=(const Spo &b) const; ostream &operator<<(ostream &os) const; // //operator int() const; int GetInt() const; }; class Lpo // LongPos positive unsigned (long) int { unsigned long int* m_lpo; }; #endif
-
Der Operator << wird sinnvollerweise nicht als Memberfunktion implementiert.
Also:
ostream& operator<<(ostream& os, const Spo& spo) { // a) os << spo.irgendwas(); // b) spo.print(os); return os; }
Bei a) muss der operator<< gegebenenfalls als friend deklariert werden.
Wobei b) den Vorteil hat, dass man es immer so machen kann und ein virtuelles print möglich wird. (hier muss dann noch die Methode print implementiert werden)Ansonsten stelle ich mir aber die Frage, was das ganze soll. Trollerei? Weshalb kannst du durch Weglassen der 0 ein Byte sparen? Und vor allem: dein Spo enthält doch einen Pointer -> das ist also doch dann insgesamt ein Bedarf von Pointergröße+int-Größe. Erscheint mir also erstmal schwachsinnig zu sein. Deine Rechnungen habe ich sicherheitshalber gar nicht näher angesehen.