这是我的问题的代码:
class ICommon
{
public:
virtual ICommon& operator=(const ICommon & p)const=0;
};
class CSpecial : public ICommon
{
public:
CSpecial& operator=(const CSpecial & cs)const
{
//custom operations
return *this;
}
};
CSpecial obj;
基本上:我希望接口ICommon强制它的后代实现=运算符,但不希望在实现中有任何类型转换。编译器说“无法实例化一个抽象类。” 任何帮助/建议将不胜感激。
答案 0 :(得分:3)
这是因为CSpecial
中函数的签名与您在抽象基类中定义的纯虚函数不同。您可以使用virtual copy constructor进行复制。基本上,您在基类中定义纯虚函数ICommon* clone() = 0
,并在每个派生类中实现它。调用此函数时,将创建调用它的对象的副本。
答案 1 :(得分:2)
为了回应Naveen所说的,CSpecial中定义的operator=()
与ICommon中定义的ICommon::operator=()
不兼容,导致过载而不是覆盖。虽然你可以使用协变返回类型(正如你所做的那样),但参数本身不能是协变的。
此外,您已将clone()
定义为const,这似乎违反直觉。在派生类中,你已经使它成为非const(如预期的那样),但同样,这使得函数签名更加不兼容。
Naveen的operator=()
想法可能是你最好的选择。否则,您可以将ICommon const引用传递给您的CSpecial dynamic_cast<>()
并在内部尝试一些{{1}}魔法,但这闻起来很有趣。
答案 2 :(得分:1)
您可以使用递归模板来实现您的目标:
template<typename T>
struct IAssignable {
virtual T& operator =(const T&) = 0;
};
struct Impl : IAssignable<Impl> {
virtual Impl& operator =(const Impl&) { return *this; }
};
这不会,也不能用于强制实现复制构造函数。所以我不相信它非常有用,你可能会更好地使用其他人建议的clone()
选项。但它一般来说是一个有用的结构。
答案 3 :(得分:0)
基本上:我想要界面 ICommon强迫它的后代 implement =运算符但不想 有任何类型转换 实现。编译说 “无法实例化一个抽象类。 任何帮助/建议将不胜感激。
考虑将基类的公共接口与其(虚拟)操作实现分开:
class ICommon
{
public:
ICommon& operator=(const ICommon & p)
{
if(this == &p)
return *this;
copy(p);
return *this;
}
protected:
virtual void copy(const ICommon& p) = 0;
};
class CSpecial : public ICommon
{
protected:
virtual void copy(const ICommon& p)
{
// TODO: copy values from p
}
};