Stellen Sie sich das folgende Beispiel:Templated Copy-Konstruktor
#include <iostream>
#include <vector>
struct Base
{
virtual void foo() = 0;
};
struct A : public Base
{
void foo() override {};
};
struct B : public Base
{
void foo() override {};
};
template <typename T>
struct C
{
struct Element
{
int x, y, z;
bool operator==(const Element& e)
{
if (x != e.x) return false;
if (y != e.y) return false;
if (z != e.z) return false;
return true;
}
};
Base* p;
std::vector<Element> v;
C()
{
p = new T();
}
void add(int x, int y, int z)
{
Element e;
e.x = x;
e.y = y;
e.z = z;
v.push_back(e);
}
void remove(int x, int y, int z)
{
Element e;
e.x = x;
e.y = y;
e.z = z;
std::vector<Element>::iterator it = std::find(v.begin(), v.end(), e);
if (p != v.end()) v.erase(p);
}
void print()
{
for (Element e : v) std::cout << e.x << " " << e.y << " " << e.z << std::endl;
}
};
int main()
{
C<A> a;
a.add(1, 2, 3);
a.add(4, 5, 6);
a.add(7, 8, 9);
a.remove(4, 5, 6);
a.print();
return 0;
}
Lassen Sie uns jetzt einen Copy-Konstruktor in C hinzufügen, so dass wir C mit einem anderen C, die einen anderen Datentyp hält (solange die Daten- initialisieren Typ stammt von Base). Das Ziel ist, dies möglich zu machen:
int main()
{
C<A> a;
a.add(1, 2, 3);
a.add(4, 5, 6);
a.add(7, 8, 9);
a.remove(4, 5, 6);
a.print();
C<B> b(a); // <----- This should be possible.
return 0;
}
Ich habe versucht, es so zu lösen:
template <typename U>
C(const C<U>& c)
{
p = new U(*c.p);
v = c.v;
}
Aber ich bekomme diese 2 Fehler von Visual Studio:
Fehler C2679 binary '=': kein Operator gefunden, der einen rechten Operanden vom Typ 'const std :: vector :: Element, std :: allocator < _Ty >>' (oder es gibt keine akzeptable Konvertierung)
Fehler C2664 'A :: A (A & &)': nicht Argument 1 von 'Base' umwandeln kann zu 'const A &'
Von dem, was ich verstanden habe, std :: vector bereits hat Zuweisungsoperator implementiert, der eine tiefe Kopie des Vektors auf der rechten Seite des Operators machen sollte.
Was mache ich also falsch und was muss ich tun, damit es funktioniert?
Sie müssen wahrscheinlich eine 'virtuelle Basis * clone() const = 0;' zu Ihrer Basisklasse hinzufügen und diese in den abgeleiteten Klassen überschreiben, um das eigentliche Klonen durchzuführen, und dann zum Kopieren von 'p' aufrufen. – evan