Anhang Q
CData Klasse
In einigen Übung wird die Klasse CData benötigt, die in der Modul-Datei CData.cxx bei den Musterlösungen definiert ist. Durch Definition des Symbols TRACE_METH in Zeile 7 kann der Aufruf der Methoden verfolgen werden.
module;
#include <print>
#include <cstdlib>
#include <iostream>
// Makro für Debug-Ausgaben
// #define TRACE_METH
#ifdef TRACE_METH
#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 CData;
export class CData
{
int* pData = nullptr; // Zeiger auf Datenfeld
size_t dSize; // Groesse Datenfeld
// Objektzaehler fuer Debug-Zwecke
inline static int objCount = 0;
int objNum; // Objektnummer
public:
// Standard-ctor (pData=nullptr!)
CData();
// ctor mit Datenfeldgroesse
CData(size_t _dSize);
// copy-ctor
CData(const CData& src);
// move-ctor
CData(CData&& src);
// Zuweisungsoperator
CData& operator = (this CData& self, const CData& src);
// move-Zuweisungsopertor
CData& operator = (this CData& self, CData&& src);
// dtor
~CData();
// Ausgabe des Datenfeldes
void Print() const;
};
CData::CData()
{
objNum = ++objCount;
TRACE(">>> ctor CData()");
}
// ctor mit Datenfeldgroesse
CData::CData(size_t _dSize)
{
dSize = _dSize;
pData = new int[dSize];
for (size_t index = 0; index < dSize; index++)
pData[index] = std::rand() % 100;
objNum = ++objCount;
TRACE(">>> ctor CData(size)");
}
// copy-ctor
CData::CData(const CData& src) :
CData(src.dSize)
{
for (size_t index = 0; index < dSize; index++)
pData[index] = src.pData[index];
TRACE(">>> copy-ctor")
}
// move ctor
CData::CData(CData&& src)
{
dSize = src.dSize;
pData = std::move(src.pData);
src.pData = nullptr; // WICHTIG!!!!
objNum = ++objCount;
TRACE(">>> move-ctor");
}
// Zuweisungsoperator
CData& CData::operator = (this CData& self, const CData& src)
{
if (&self == &src) // keine Zuweisung auf sich selbst!
return self;
delete[] self.pData; // bisherige Daten freigeben
self.dSize = src.dSize; // neue Daten uebernehmen
self.pData = new int[self.dSize];
for (size_t index = 0; index < self.dSize; index++)
self.pData[index] = src.pData[index];
TRACES("operator =");
return self;
}
// move-Zuweisungsopertor
CData& CData::operator = (this CData& self, CData&& src)
{
if (&self == &src) // keine Zuweisung auf sich selbst!
return self;
delete[] self.pData; // bisherige Daten loeschen
self.dSize = src.dSize; // neue Daten uebernehmen
self.pData = src.pData; // durch Zuweisung des Zeigers
src.pData = nullptr; // WICHTIG!!!!
TRACES("move-operator =");
return self;
}
// dtor
CData::~CData()
{
delete[] pData;
TRACE("<<< dtor");
}
// Ausgabe des Datenfeldes
void CData::Print() const
{
std::println("Daten Objekt {}:\t", objNum);
for (size_t index = 0; index < dSize; index++)
std::print("{:3},", pData[index]);
std::println();
}