Pergunta

See the following code:

struct Object;

struct Component
{
    Component(Object* obj) { }
};

struct Renderable : public virtual Component
{
    virtual void Render() = 0;
};

struct AnimationRenderer : public Renderable
{
    AnimationRenderer(Object* obj) : Component(obj) { }
    virtual void Render() { }
};

This fails to compile, because there is no matching call to Component::Component() from Renderable::Renderable().

I can make this sample work by giving Renderable a constructor such as Renderable() : Component(NULL) { }, even though Renderable will never be able to initialize Component.

Because Renderable is an abstract class, it can never be instantiated directly. Because it virtually inherits from Component, it will never be able to invoke initialization of Component.

What is the reason for the language requiring code that will never/can never be invoked?

Foi útil?

Solução

Actually, the language doesn't require that. Your compiler is not using the current C++ rules.

12.6.2p8 says (boldface mine for emphasis):

[ Note: An abstract class is never a most derived class, thus its constructors never initialize virtual base classes, therefore the corresponding mem-initializers may be omitted. — end note ]

I can't find that rule in C++03, so this is a recognized flaw in C++ that has since been fixed. Look for a compiler update that supports C++11.

The closest related rule in C++03 I can find was in section 12.6.2p6:

A mem-initializer naming a virtual base class shall be ignored during execution of the constructor of any class that is not the most derived class.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top