Rei*_*ica 6 c++ inheritance multiple-inheritance
我不确定要使用的术语,但这是我的例子:
class Base {
public:
    virtual void test() = 0;
};
class Mixin {
public:
    virtual void test() { }
};
class Example : public Base, public Mixin {
};
int main(int argc, char** argv) {
    Example example;
    example.test();
    return 0;
}
我希望我的Mixin类实现纯虚函数Base::test,但是当我编译它时,它说:
test.cpp: In function ‘int main(int, char**)’:
test.cpp:15:13: error: cannot declare variable ‘example’ to be of abstract type ‘Example’
     Example example;
             ^
test.cpp:11:7: note:   because the following virtual functions are pure within ‘Example’:
 class Example : public Base, public Mixin {
       ^
test.cpp:3:18: note:    virtual void Base::test()
     virtual void test() = 0;
                  ^
test.cpp:16:13: error: request for member ‘test’ is ambiguous
     example.test();
             ^
test.cpp:8:18: note: candidates are: virtual void Mixin::test()
     virtual void test() { }
                  ^
test.cpp:3:18: note:                 virtual void Base::test()
     virtual void test() = 0;
                  ^
我可以添加一个using声明,使其不含糊:
class Example : public Base, public Mixin {
public:
    using Mixin::test;
};
但它说我还没有实现它:
test.cpp: In function ‘int main(int, char**)’:
test.cpp:17:13: error: cannot declare variable ‘example’ to be of abstract type ‘Example’
     Example example;
             ^
test.cpp:11:7: note:   because the following virtual functions are pure within ‘Example’:
 class Example : public Base, public Mixin {
       ^
test.cpp:3:18: note:    virtual void Base::test()
     virtual void test() = 0;
                  ^
是否有可能做到这一点?
我知道一个选项是Mixin继承Base,但在我的情况下,有几个派生类,他们不共享一个共同的祖先.
您不能直接让类覆盖不是其基类的方法.但是你可以用迂回的方式来做.我将介绍两种这样的方法 - 我更喜欢第二种方法.
Daniel Paul在thinkbottomup.com.au上的一篇文章中描述了这一点,题为C++ Mixins - 通过继承重用是好的......当以正确的方式完成时.
在你的情况下,这是它的样子:
class Base {
public:
    virtual void test() = 0;
};
template <typename T>
class Mixin : public T {
public:
    virtual void test() override { /*... do stuff ... */ }
};
class UnmixedExample : public Base {
    /* definitions specific to the Example class _not_including_
       a definition of the test() method */
};
using Example = class Mixin<UnmixedExample>;
int main(int argc, char** argv) {
    Example{}.test();
    return 0;
}
CRTP是"奇怪的重复模板模式" - 如果您之前没有看过它,请务必遵循该链接.使用这种方法,我们将使用virtual继承说明符来避免歧义,与前一种方法不同 - 我们不会颠倒Mixin和Example类的继承顺序.
class Base {
public:
    virtual void test() = 0;
};
template <typename T>
class Mixin : virtual T {
public:
    virtual void test() override { /*... do stuff ... */ }
};
class Example : public virtual Base, public virtual Mixin<Base> {
    /* definitions specific to the Example class _not_including_
       a definition of the test() method */
};
int main(int argc, char** argv) {
    Example{}.test();
    return 0;
}
注意两种解决方案:
| 归档时间: | 
 | 
| 查看次数: | 1332 次 | 
| 最近记录: |