我有以下情况:
class Fork {
public:
virtual void use() = 0;
};
class Spoon {
public:
virtual void use() = 0;
};
class SilverSpoon : public Spoon {
public:
virtual void use() { }
};
class SilverSpork : public SilverSpoon, public Fork {
public:
using SilverSpoon::use;
};
我希望Fork::use
中的SilverSpoon::use
定义纯虚函数SilverSpork
。但是,我得到了
error: cannot declare variable ‘spork’ to be of abstract type ‘SilverSpork’
note: because the following virtual functions are pure within ‘SilverSpork’:
note: virtual void Fork::use()
有没有办法解决这个问题而无需添加
virtual void use() {
SilverSpoon::use();
}
到SilverSpork
?
答案 0 :(得分:4)
Fork
和Spoon
之间没有固有的联系,而且它们都有一个名为use
的虚函数这一事实并没有成功。但是,如果您添加一个新类,比如Utensil
定义一个纯虚函数use()
,并从中导出Fork
和Spoon
作为虚拟基础,那么有联系。这样,班级SilverSpork
将选择SilverSpoon::use
的实施作为其直接基地use
中Fork
的替代者。这被称为“支配地位”。
class Utensil {
public:
virtual void use() = 0;
};
class Spoon : public virtual Utensil {
public:
virtual void use() = 0; // or can omit this, relying on Utensil
};
class Fork : public virtual Utensil {
public:
virtual void use() = 0; // or can omit this, relying on Utensil
};
class SilverSpoon : public Spoon {
public:
void use() { }
};
class SilverSpork : public SilverSpoon, public Fork {
}; // OK: SilverSpoon::use overrides Fork::use
答案 1 :(得分:2)
Fork::use()
和Spoon::use()
是两种具有相同名称的不同方法,可扩展为SilverSpork
。
编译器希望它们都能实现。它只是一个冲突而不是覆盖或超载的名称。可能性是从基础虚拟类继承Fork和Spoon:
class Object {
public:
virtual void use() = 0;
};
class Fork : virtual public Object {
};
class Spoon: virtual public Object {
};
class SilverSpoon : public Spoon {
public:
virtual void use() { cout << "SilverSpoon" << endl; }
};
class SilverSpork : public SilverSpoon, public Fork {
public:
using SilverSpoon::use;
};
图:
+---------------+
| Object |
+---------------+
^ ^
| |
| |
| |
+---------------+ +---------------+
| Spoon | | Fork |
+---------------+ +---------------+
^ ^
| |
| |
| |
+---------------+ |
| SilverSpoon | |
+---------------+ |
^ |
| |
| |
| |
+---------------+
| SilverSpork |
+---------------+
答案 2 :(得分:2)
由于您使用多重继承,因此您实际上继承了两种不同的抽象use
方法,并且必须在您的孩子中覆盖两者。
您需要问自己的第一个问题是SilverSpork
与use
具有相同SilverSpoon
行为的原因。如果确实如此,我无法相信我会建议这样做,但你可以通过使用钻石继承和新的虚拟基础来解决这个问题:
class Utinsil
{
public:
virtual void use() = 0;
};
class Fork : public virtual Utinsil {
};
class Spoon : public virtual Utinsil {
};
class SilverSpoon : public Spoon {
public:
virtual void use() { }
};
class SilverSpork : public SilverSpoon, public Fork {
};
int main()
{
SilverSpork silver_spork;
}