Je souhaite ajouter une fonctionnalité d'échange à deux classes C++ existantes. Une classe hérite de l'autre. Je souhaite que les instances de chaque classe ne puissent être échangées qu'avec des instances de la même classe. Pour le rendre semi-concret, disons que j'ai des cours Foo et Bar. Bar hérite de Foo. Je définis Foo :: swap (Foo &) et Bar :: swap (Bar &). Bar :: échange les délégués vers Foo :: swap. Je veux que Foo :: swap ne fonctionne que sur les instances de Foo et que Bar :: swap ne fonctionne que sur les instances de barre: je n'arrive pas à comprendre comment appliquer cette exigence.Problème d'échange C++ dans le scénario d'héritage
Voici un échantillon de ce qui me donne du mal:
#include <algorithm>
#include <iostream>
struct Foo {
int x;
Foo(int x) : x(x) {};
virtual void swap(Foo &other) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
std::swap(this->x, other.x);
};
};
struct Bar : public Foo {
int y;
Bar(int x, int y) : Foo(x), y(y) {};
virtual void swap(Bar &other) {
std::cout << __PRETTY_FUNCTION__ << " ";
Foo::swap(other);
std::swap(this->y, other.y);
};
};
void display(Foo &f1, Foo &f2, Bar &b34, Bar &b56)
{
using namespace std;
cout << "f1: " << f1.x << endl;
cout << "f2: " << f2.x << endl;
cout << "b34: " << b34.x << " " << b34.y << endl;
cout << "b56: " << b56.x << " " << b56.y << endl;
}
int main(int argc, char **argv)
{
{
Foo f1(1), f2(2);
Bar b34(3,4), b56(5,6);
std::cout << std::endl << "Initial values: " << std::endl;
display(f1,f2,b34,b56);
}
{
Foo f1(1), f2(2);
Bar b34(3,4), b56(5,6);
std::cout << std::endl << "After Homogeneous Swap: " << std::endl;
f1.swap(f2); // Desired
b34.swap(b56); // Desired
display(f1,f2,b34,b56);
}
{
Foo f1(1), f2(2);
Bar b34(3,4), b56(5,6);
std::cout << std::endl << "After Heterogeneous Member Swap: " << std::endl;
// b56.swap(f2); // Doesn't compile, excellent
f1.swap(b34); // Want this to not compile, but unsure how
display(f1,f2,b34,b56);
}
return 0;
}
Voici le résultat:
Initial values:
f1: 1
f2: 2
b34: 3 4
b56: 5 6
After Homogeneous Swap:
virtual void Foo::swap(Foo&)
virtual void Bar::swap(Bar&) virtual void Foo::swap(Foo&)
f1: 2
f2: 1
b34: 5 6
b56: 3 4
After Heterogeneous Member Swap:
virtual void Foo::swap(Foo&)
f1: 3
f2: 2
b34: 1 4
b56: 5 6
Vous pouvez le voir dans le groupe de sortie finale où f1.swap (B34) "découpé en tranches" b34 d'une manière potentiellement méchante. Je voudrais que la ligne coupable ne soit pas compilée ou explosée à l'exécution. En raison de l'héritage impliqué, je pense que je rencontre le même problème si j'utilise une implémentation de non-membre ou d'échange d'ami.
Le code est disponible à codepad si cela aide. Ce cas d'utilisation est dû à I want to add swap to boost::multi_array and boost::multi_array_ref. multi_array hérite de multi_array_ref. Cela n'a de sens que d'échanger multi_arrays avec multi_arrays et multi_array_refs avec multi_array_refs.
Vraiment moche, mais je pense que c'est la seule chose qui est réalisable en pratique. Merci Douglas. –