A
Hmm, ich glaube hier gibt es ein kleines Verständnisproblem, was Vererbung angeht.
Kommt dynamische Vererbung (ist das mit virtual) zum Einsatz, muss immer ein virtueller Destruktor vorhanden sein. Du bekommmst sonst Probleme beim Abbau von Objekten.
Ich gebe mal ein allgemeines Beispiel, dass die Probleme aufklären sollte. Ich versuche es auch gleichzeitig anhand eines praktischen Beispiels zu zeigen.
Hier wäre die Definition, also Vector.hxx (ich gehöre zu den Leuten, die .cxx und .hxx verwenden)
#include <string>
// --- Vector2 ---
class Vector2 {
public:
// --- Vector2: public data structures ---
float x;
float y;
// --- constructors and deconstructors ---
Vector2();
Vector2(const float& xx, const float& yy);
Vector2(const Vector2& rhs);
virtual ~Vector2();
// --- Vector2: base operators ---
Vector2& operator=(const Vector2& rhs);
bool operator==(const Vector2& rhs) const;
bool operator!=(const Vector2& rhs) const;
// --- Vector2: default methods ---
virtual std::string string() const;
};
// --- Vector3 ---
class Vector3 : public Vector2 {
public:
// --- Vector3: publioc data structures ---
float z;
// --- Vector3: constructors and deconstructors ---
Vector3();
Vector3(const Vector2& vec, const float&& zz = 0.0);
Vector3(const float& xx, const float&& yy, const float&& zz);
Vector3(const Vector3& rhs);
virtual ~Vector3();
// --- Vector3: base operators ---
Vector3& operator=(const Vector3& rhs);
bool operator==(const Vector3& rhs) const;
bool operator!=(const Vector3& rhs) const;
// --- Vector3: public methods ---
virtual std::string string() const;
};
Und hier kommt die Implementierung, also Vector.cxx ...
#include <sstream>
#include "Vector.hxx"
// --- Vector2: constructors and deconstructors ---
Vector2::Vector2()
: x(0.0), y(0.0)
{
}
Vector2::Vector2(const float& xx, const float& yy)
: x(xx), y(yy)
{
}
Vector2::Vector2(const Vector2& rhs)
: x(rhs.x), y(rhs.y)
{
}
Vector2::~Vector2()
{
}
// --- Vector2: base operators ---
Vector2& Vector2::operator=(const Vector2& rhs)
{
if (this != &rhs)
{
x = rhs.x;
y = rhs.y;
}
return *this;
}
bool Vector2::operator==(const Vector2& rhs) const
{
return x == rhs.x &&
y == rhs.y;
}
bool Vector2::operator!=(const Vector2& rhs) const
{
return !(*this == rhs);
}
// --- Vector2: public methods ---
std::string Vector2::string() const
{
std::stringstream result;
result << x << ", "
<< y;
return result.str();
}
// --- Vector3: constructors and deconstructors ---
Vector3::Vector3()
: Vector2(0.0, 0.0), z(0.0)
{
}
Vector3::Vector3(const Vector2& vec, const float& zz)
: Vector2(vec), z(zz)
{
}
Vector3::Vector3(const float& xx, const float& yy, const float& zz)
: Vector2(xx, yy), z(zz)
{
}
Vector3::Vector3(const Vector3& rhs)
: Vector2(rhs.x, rhs.y), z(rhs.z)
{
}
Vector3::~Vector3()
{
}
// --- Vector3: base operators ---
Vector3& Vector3::operator=(const Vector3& rhs)
{
if (this != &rhs)
{
Vector2::operator=(rhs);
z = rhs.z;
}
return *this;
}
bool Vector3::operator==(const Vector3& rhs) const
{
return Vector2::operator==(rhs) &&
z == rhs.z;
}
bool Vector3::operator!=(const Vector3& rhs) const
{
return !(*this == rhs);
}
// --- Vector3: public methods ---
std::string Vector3::string() const
{
std::stringstream result;
result << Vector2::string() << ", "
<< z;
return result.str();
}
Das sollte eine halbwegs elegante Implementierung sein, die in Sachen Vererbung alles beachtet, was es zu beachten gibt. Und ich hoffe mal, dass sich kein Typo eingeschlichen hat. Das sollte man problemlos 1:1 verwenden können.
Wenns Fragen gibt, dann nur zu