Search code examples
c++classparametersderived-class

How to properly override function with different arguments in derived class?


I'm making a simple MVC example for c++ classes at my uni. First, look at the code: The executor.h part:

    class IExecutor {
    IParams params;
public:
    virtual void initialize(IParams iParams);
    virtual void execute();
};

class QEExec : public IExecutor {
public:
    void initialize(QEParams iParams) override;
    void execute() override;
};

And now params.h part:

class IParams {

};

class QEParams : public IParams {
public:
    int a;
    int b;
    int c;
};

The problem is that I want to create void initialize(QEParams iParams) function for QEExec and pass QEParams to it in order to have access to a, b, and c parameters (I'll need that later) but I can't do so because of virtual void initialize(IParams). I thought that if QEParams is derives from IParams I will be able to do so, but I can't access parameters that I mentioned earlier. How to make it work so that I'll be able to access a, b and c parameters in initialize function? EDIT: I'll put a photo of how it should look like: https://i.sstatic.net/KWaSQ.jpg


Solution

    1. Interface doesn't have any fields
    2. Interface has only pure virtual methods
    3. Name initialize of IExecutor indicates some misunderstanding. Looks like it suppose to be called once at the begging during construction time. It should be hidden in step where some factory creates object implementing IExecutor

    So basically I'm suspecting you need more something like this:

    class IExecutor
    {
    public:
        virutal ~IExecutor() {}
        virtual void execute() = 0;
    };
    
    struct QEParams {
        int a;
        int b;
        int c;
    };
    
    class QEExec: public IExecutor
    {
    public:
        QEExec(int b, int c) ....
    
        void initialie(); // second step init
    
        void execute() override;
    };
    
    class CAExec: public SomeOtherBaseClass, public IExecutor
    {
    public:
        CAExec(int a, int c) ....
    
        void execute() override;
    };
    
    std::unique_ptr<IExecutor> executorFactory(const QEParams& params)
    {
        if (params.a < 0) {
            auto result = std::make_unique<QEExec>(params.b, params.c);
            result->initialie();
            return result;
        }
        return std::make_unique<CAExec>(params.a, params.c);
    }
    

    Usually factory parameters are structural data and extra abstraction is obsolete.

    If different kind of arguments are needed to create alternative version of IExecutor you just provide different factory function (possibly overload):

    std::unique_ptr<IExecutor> executorFactory(const std::string& fileName)
    {
        ....
    }