Anhang T
Erweiterte Klasse CData4
Erweiterte Version von CData3 mit der Moeglichkeit, CData4-Objekte mit println() auszugeben.
// Erweiterte Version von CData3 mit der Moeglichkeit,
// CData4-Objekte mit println() auszugeben
module;
#include <iostream>
#include <string>
#include <string_view>
#include <stdexcept>
// Makro für Debug-Ausgaben
//#define TRACE_METH
#ifdef TRACE_METH
#include <print>
#define TRACE(T_) std::println("Obj-Nr:{} {}",objNum,T_);
#define TRACES(T_) std::println("Obj-Nr:{} {}",self.objNum,T_);
#else
#define TRACE(T_)
#define TRACES(T_)
#endif
export module CData4;
export class CData4
{
std::string text;
// Objektzaehler fuer Debug-Zwecke
inline static int objCount = 0;
int objNum; // Objektnummer
public:
// Standard-ctor
CData4();
// ctor mit Text
CData4(std::string_view _text);
// copy-ctor
CData4(const CData4& src);
// move-ctor
CData4(CData4&& src);
// Zuweisungsoperator
CData4& operator = (this CData4& self, const CData4& src);
// move-Zuweisungsopertor
CData4& operator = (this CData4& self, CData4&& src);
// dtor
~CData4();
// Ausgabe des Datenfeldes
friend std::ostream& operator << (std::ostream& out, const CData4& obj);
// Ueberladener Indexoperator
auto operator [] (size_t index);
// space-operator
auto operator <=> (this const CData4& self, const CData4& op2);
// Vergleich auf Gleichheit
bool operator == (const CData4& op2) const;
// Fuer print() und format()
friend struct std::formatter<CData4>;
};
// Standard-ctor
CData4::CData4()
{
objNum = ++objCount;
TRACE(">>> ctor CData4()");
}
// ctor mit Datenfeldgroesse
CData4::CData4(std::string_view _text): text(_text)
{
objNum = ++objCount;
TRACE(">>> ctor CData4(text)");
}
// copy-ctor
CData4::CData4(const CData4& src): text(src.text)
{
objNum = ++objCount;
TRACE(">>> copy-ctor")
}
// move ctor
CData4::CData4(CData4&& src)
{
// Der move-ctor von std::string versetzt das
// Quellobjekt in einen gueltigen Zustand
text = std::move(src.text);
objNum = src.objNum;
TRACE(">>> move-ctor");
}
// Zuweisungsoperator
CData4& CData4::operator = (this CData4& self, const CData4& src)
{
if (&self == &src) // keine Zuweisung auf sich selbst!
return self;
self.text = src.text; // neue Daten uebernehmen
TRACES("operator =");
return self;
}
// move-Zuweisungsopertor
CData4& CData4::operator = (this CData4& self, CData4&& src)
{
if (&self == &src) // keine Zuweisung auf sich selbst!
return self;
self.text = std::move(src.text); // neue Daten uebernehmen
TRACES("move-operator =");
return self;
}
// dtor
CData4::~CData4()
{
TRACE("<<< dtor");
}
// Ueberladener Indexoperator
auto CData4::operator [] (size_t index)
{
if ((index < 0) || (index >= text.length()))
throw std::out_of_range("Index ausserhalb des Bereichs!");
return text[index];
}
// Ausgabe des Datenfeldes
export std::ostream& operator << (std::ostream& out, const CData4& obj)
{
out << obj.text;
return out;
}
// space-operator
auto CData4::operator <=> (this const CData4& self, const CData4& op2)
{
// Nun die Daten vergleichen
// Aufruf des operators ==
return (self == op2) <=> true;
}
// Vergleich auf Gleichheit
bool CData4::operator == (const CData4& op2) const
{
// Nun die Daten vergleichen
return text == op2.text;
}
// Spezialisertes formatter-Template fuer
// den Datentyp CData4
template<>
struct std::formatter<CData4>
{
constexpr auto parse(auto& ctx)
{
// Formatspezifikation analysieren
// hier noch nicht erforderlich
return ctx.begin();
}
auto format(const CData4& s,
std::format_context& ctx) const
{
// format_to() zur formatierten Ausgabe aufrufen
// Formatierte Daten in Puffer den ctx.out() liefert
return std::format_to(ctx.out(),
"{}",s.text);
}
};
export extern template struct std::formatter<CData4>;