1

我有以下情况:

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::usein定义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

4

3 回答 3

4

Fork和之间没有内在的联系Spoon,而且它们都有一个名为的虚函数这一事实use并没有产生联系。但是,如果您添加一个新类,比如说,Utensil它定义了一个纯虚函数use(),并从它派生ForkSpoon从它作为一个虚基,您就有了一个连接。这样,该类SilverSpork 在其直接基类中选择 的实现SilverSpoon::use作为覆盖器。这被称为“支配地位”。useFork

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
于 2013-04-19T17:20:59.003 回答
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  |
                                   +---------------+
于 2013-04-19T17:16:59.510 回答
2

由于您使用多重继承,您实际上继承了两个不同的抽象方法,并且您必须在您的孩子中use覆盖它们。

您需要问自己的第一个问题是为什么 aSilverSpork具有与 a 相同的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;
}
于 2013-04-19T17:22:38.833 回答