在另一个模板基类中实现抽象基类函数

时间:2010-12-14 16:53:15

标签: c++ templates compiler-errors

我有一个Visual Studio 2008 C ++项目,其中我有一个继承自抽象基类的类和另一个在抽象基类中实现函数的模板类。例如:

class Foo;

struct Buzz
{
    virtual ~Buzz() {};
    virtual void Buzz_Do( Foo* ) = 0;
};

class Base
{
public:
    virtual ~Base() {};
    virtual void Base_Do( Buzz* ) = 0;
};

template< class T >
class Bar
{
public:
    virtual void Base_Do( Buzz* v )
    {
        v->Buzz_Do( static_cast< T* >( this ) );
    };
};

class Foo : public Base, public Bar< Foo >
{
};

int _tmain(int argc, _TCHAR* argv[])
{
    Foo c;
    return 0;
}

不幸的是,这会产生编译器错误:

1>MyApp.cpp(39) : error C2259: 'Foo' : cannot instantiate abstract class
1>        due to following members:
1>        'void Base::Base_Do(Buzz *)' : is abstract
1>        MyApp.cpp(17) : see declaration of 'Base::Base_Do'

我尝试将公开using Bar< Foo >::Base_Do;添加到class Foo,但这没有帮助。

有没有办法让这项工作或我需要在Base_Do()中使用具体的Foo实施而不使用Bar<>

谢谢, PaulH

7 个答案:

答案 0 :(得分:4)

如果可能,让Bar<>派生自Base, 和Foo只来自Bar<T>

答案 1 :(得分:2)

就编译器而言,模板函数实际上从基类实现了该函数。编译器认为Base::Base_DoBar<T>::Base_Do是两个完全不相关的函数,而不是一个函数的实现。

编译器看到的是Foo结束了两个(几乎)同名的函数:Base::Base_DoBar<T>::Base_Do。 Bar根本没有实现Base的界面。

我认为您真正想要的是Bar<T>继承Base并实施Base_Do。然后让Foo仅从Bar<Foo>继承。

但即便如此,你能否更清楚地告诉我们你正在尝试解决的问题?然后我们可以就如何解决这个问题提供建议。 BuzzFoo以及FooBarBase之间的关系让我感到困惑。

编辑: 另请参阅http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.10,因为这可能会提供一种替代机制,仍允许您使用mixin。

答案 2 :(得分:2)

当这些基数不相关时,无法使一个基类中定义的函数在另一个基数中使用相同名称覆盖函数。它不起作用。您必须让您的模板库继承自抽象基础,或者在派生类中编写函数以在非抽象基础中调用该函数。

你做的很大程度上取决于你的问题。我通常更喜欢前者,但遇到了不可能的情况(因为我需要的基础根本就没有关联)并使用后者。

答案 3 :(得分:1)

你试过了吗?

template< class T , class K>

class Bar: public K
{
public:
    virtual void Base_Do( Buzz* v )
    {
        v->Buzz_Do( static_cast< T* >( this ) );
    };
};

class Foo : public Bar< Foo, Base >
{
};

Foo派生自Base,其中包含未定义的虚方法。你可以像我写的那样或者做出派生virtual

答案 4 :(得分:0)

由于Foo在实例化Foo(Foo c;)之前扩展了Base,因此需要实现Base的所有虚方法。在您的示例中,您需要实现virtual void Base_Do( Buzz* )

答案 5 :(得分:0)

查看错误:

> 1>MyApp.cpp(39) : error C2259: 'Foo' :
> cannot instantiate abstract class 1>  
> due to following members: 1>       
> 'void Base::Base_Do(Buzz *)' : is
> abstract 1>        MyApp.cpp(17) : see
> declaration of 'Base::Base_Do'

Foo是一个抽象类。您无法创建它的实例。首先实现它从基类继承的所有虚函数。

答案 6 :(得分:0)

  

我有一个Visual Studio 2008 C ++   项目,我有一个类   继承自虚拟基类和   另一个实现的模板类   虚拟基类中的一个函数。

  • 错误:您的代码没有虚拟基类。

这是你的代码(正如我写的那样):

class Foo;

struct Buzz
{
    virtual ~Buzz() {};
    virtual void Buzz_Do( Foo* ) = 0;
};

class Base
{
public:
    virtual ~Base() {};
    virtual void Base_Do( Buzz* ) = 0;
};

template< class T >
class Bar
{
public:
    virtual void Base_Do( Buzz* v )
    {
        v->Buzz_Do( static_cast< T* >( this ) );
    };
};

class Foo : public Base, public Bar< Foo >
{
};

int _tmain(int argc, _TCHAR* argv[])
{
    Foo c;
    return 0;
}

此外,

  • 错误:纯虚拟成员函数Buzz_Do未在任何地方实现。

  • 错误:您的代码缺少main功能(虽然读者可以提供一个,我猜)。

  • 错误:宏(或类型)_TCHAR无法定义。

话虽如此,虚拟继承 - 您声称您的实际代码正在使用 - 是您可能要提出的问题的一个可能答案。

然而,由于您的无效呈现代码和关于该代码的错误断言,可以合理地说出来。我注意到其他人都试过了。也许,如果你很幸运,其中一个答案符合要求,但这只是一场机会游戏。

干杯&amp;第h。,