implementing an abstract base class function in an

2019-08-18 03:26发布

问题:

I have a Visual Studio 2008 C++ project where I have a class that inherits from an abstract base class and another template class that implements a function in the abstract base class. For example:

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;
}

Unfortunately, this yields the compiler error:

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'

I've tried adding a public using Bar< Foo >::Base_Do; to class Foo, but that did not help.

Is there a way to make this work or will I need to put a concrete Base_Do() implementation in Foo and not use Bar<>?

Thanks, PaulH

回答1:

If possible let the Bar<> derive from Base, and Foo derive only from Bar<T>.



回答2:

There is no way to cause a function defined in one base to override a function by the same name in another base when those bases are unrelated. It doesn't work that way. You either have to have your template base inherit from the abstract base, or write the function in your derived class to call the function in your non-abstract base.

Which you do depends greatly upon your problem. I generally prefer the former but have run into situations where it is not possible (because the bases I need are simply not related) and use the latter.



回答3:

As far as the compiler can tell, your template function doesn't actually implement the function from the base class. The compiler thinks that Base::Base_Do and Bar<T>::Base_Do are two completely unrelated functions, NOT an implementation of one.

What the compiler sees is that Foo winds up with two functions of (almost) the same name: Base::Base_Do and Bar<T>::Base_Do. Bar doesn't implement Base's interface at all.

I think what you really want is for Bar<T> to inherit from Base and implement Base_Do. Then have Foo inherit just from Bar<Foo>.

But even with all that, can you tell us more clearly what problem you're actually trying to solve? Then we can offer advice on how to solve that. The relationship between Buzz and Foo, and Foo to Bar and Base confuses me.

EDIT: Also see http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.10 as that might offer an alternative mechanism that still allows you to use the mixin.



回答4:

Have you tried:

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 deriver from Base, which has undefined virtual method. You could make it like I wrote or make derivation virtual.



回答5:

Since Foo extends Base, before instantiating Foo (Foo c;), you need to implement all virtual methods of Base. In your example, you need to implement virtual void Base_Do( Buzz* ).



回答6:

Look at the error:

> 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 is an abstract class. You cannot create instance of it. First implements all the virtual functions it inherits from the base classes.



回答7:

I have a Visual Studio 2008 C++ project where I have a class that inherits from a virtual base class and another template class that implements a function in the virtual base class.

  • Wrong: Your code has no virtual base classes.

Here is your code (as I'm writing this):

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;
}

Further,

  • Wrong: The pure virtual member function Buzz_Do is not implemented anywhere.

  • Wrong: Your code lacks a main function (although readers could supply one, I guess).

  • Wrong: The macro (or type) _TCHAR is nowhere defined.

Having said that, virtual inheritance – which you claim that your actual code is using – is one possible answer to the question that it seems you intended to ask.

However, with your invalid presented code and incorrect assertions about that code, not much can reasonably be said. I note that others have tried anyway. Perhaps, if you're lucky, one of those answers will fit the bill, but it's just a game of chance.

Cheers & hth.,