可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.,