Calling protected ctor of inheriting class from within static template method of base class fails

佐手、 提交于 2019-12-05 21:48:01

问题


I have a component class that defines a static template method of how a Component should be created in general:

class Component {
protected:
    uint32_t id;

    Component(uint32_t id) :
            id(id) {
    }

    template<typename T, uint32_t C>
    static T* createComponent() {
        // content here not relevant
        return new T(someParameter);
    }

};

Then there is an implementation, for example a Button. The constructor of this class should not be used directly, instead there is a static method that calls the Component::createComponent template function.

class Button: public Component {
protected:
    Button(uint32_t id) :
            Component(id) {
    }
public:
    static Button* create();
};

The implementation looks like this, passing the type to instantiate and a constant thats used in creation:

Button* Button::create() {
    return createComponent<Button, UI_COMPONENT_BUTTON>();
}

Now the problem is, that the compiler complains with "error: 'Button::Button(uint32_t)' is protected". For my understanding, this constructor call should be OK as Button extends Component, but this seems to be a problem here.

How can I solve this?


回答1:


Since your create() function won't be able to deal with further inherited classes you can take advantage of this and not create a Button but, instead, a generic derived, protected, derived class which would have access to your protected constructor:

class Component {
    uint32_t id;
    template <typename T>
    struct Concrete: T {
        Concrete(uint32_t id): T(id) {}
    };
protected:
    Component(uint32_t id) :
        id(id) {
    }

    template<typename T, uint32_t C>
    static T* createComponent() {
        // content here not relevant
        return new Concrete<T>(C);
    }
};

class Button:
    public Component {
protected:
    Button(uint32_t id): Component(id) {}
public:
    static Button* create() {
         return createComponent<Button, UI_COMPONENT_BUTTON>();
    }
};



回答2:


Access specifier of Button constructor is protected that means it can only be accessed by classes derived from Button. If you want your code to work then you have to make that constructor public.




回答3:


"Button" extends "Component", so "Button" can access protected members of "Component", but "Component" does not know about "Button", and so cannot access it's protected members.



来源:https://stackoverflow.com/questions/27529000/calling-protected-ctor-of-inheriting-class-from-within-static-template-method-of

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!