この 2 つのクラスがあり、スワップ イディオムが実装されているとします。基底クラスのコピー コンストラクターと代入演算子は、意味がないため削除されます。ただし、メンバーを保持するため、スワップメソッドが実装されています。
namespace std
{
template<>
void swap<Base>(Base& a, Base& b)
{
a.swap(b);
}
template<>
void swap<Derived>(Derived& a, Derived& b)
{
a.swap(b);
}
}
class Base
{
public:
Base(int ID) : ID_(ID) {}
virtual std::string getString()=0;
Base(const Base&)=delete;
operator=(const Base&)=delete;
void swap(Base& rhs)
{
std:swap(ID_, rhs.ID_);
}
private:
int ID_;
}
class Derived : public Base
{
public:
Derived(int ID, bool Value) : Base(ID), Value_(Value) {}
virtual ~Derived() {}
Derived(Derived& rhs)
{
std::swap(*this, rhs);
}
virtual std::string getString() {return Value_ ? "True" : "False"}
void swap(Derived& lhs, Derived& rhs)
{
std::swap(static_cast<Base&>(lhs), static_cast<Base&>(rhs);
std::swap(lhs.Value_, rhs.Value_);
}
private:
bool Value_;
}
多くの例で見られるように、これは標準的な方法だと思います。ただし、パブリック Base::swap に問題があることがわかりました。抽象基本クラスだけを交換することはできないはずです。
Base クラスのテンプレートを削除し、Base::swap メソッドを保護した方がよいのではないでしょうか。
class Base
{
...
protected:
void swap(Base& rhs, Base &lhs);
}
class Derived : public Base
{
...
public:
void swap(Derived& lhs, Derived& rhs)
{
Base::swap(static_cast<Base&>(lhs), static_cast<Base&>(rhs);
std::swap(lhs.Value_, rhs.Value_);
}
}
base から派生した別のクラスがあると仮定すると、最初の実装では ID を交換できますが、派生オブジェクトのデータ メンバーは同じままです。
では、抽象クラスのスワッピングは外部から可能であってはならないという考えでよろしいでしょうか?