假设我们有这两个类,并实现了交换习语。基类的复制构造函数和赋值运算符被删除,因为它没有意义。然而,交换方法被实现,因为它拥有一个成员。
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_);
}
}
假设有另一个从基类派生的类,第一个实现可以交换 ID,但是派生对象的数据成员将保持不变。
那么,我是否正确地认为从外部交换抽象类是不可能的?