简体   繁体   中英

Architecture of sub-classes in C++

I learn C++ OOP-paradigm and want to ask related question:

Assumption

We have a base class:

class Base { 
public:
    virtual SomeType PowerMethod() { return SomeType{} };
}

We have a variable target and subclass which realizes some calculations with target variable based on the constructor's parameter (simple calculations or complicated calcs):

class Calc : public Base {
public: // using only public access to simplify real code structure
    SomeType target;
    void Simple() { target = 1; };
    void Complex(){ target = 10000; };

    explicit Calc(bool isSimple) { 
        if(isSimple) 
            Simple(); 
        else
            Complex();
    }
};

Question

How to optimally realize two classes which based on different methods (Simple or Complex) but provide the same functionality of PowerMethod()?

My solution

class SimpleCalc : public Calc {
    bool isSimple = true;
public:
    SomeType PowerMethod() override { 
        Calc CalcInstance(isSimple);
        return CalcInstance.target;
    };
};


class ComplexCalc : public Calc {
    bool isSimple = false;
public:
    SomeType PowerMethod() override { 
        Calc CalcInstance(isSimple);
        return CalcInstance.target;
    };
};

This solution is pretty "ugly" and I want to ask you how to make it more readable.

Thank you!

I think that in your code, you didn't mean to craete a new Calc object, but instead call it on the superclass. This can be done like so:

Calc::Simple();

You can override the method PowerMethod , but still call the superclass's code:

virtual SomeType PowerMethod() override {
   //do something
   Base::PowerMethod();
}

If your problem is more complicated, and polymorphism and superclasses can't help you, you can always declare some method protected, so that only subclasses can access it. So, you could for example do this:

class Calc : public Base {
protected:
    SomeType target;
    void Simple() { target = 1; };
    void Complex(){ target = 10000; };
public:
    explicit Calc(bool isSimple) { 
        if(isSimple) 
            Simple(); 
        else
            Complex();
    }
};
class SimpleCalc : public Calc {
public:
    SomeType PowerMethod() override { 
        Calc::Simple();
        return Calc::target;
    };
};


class ComplexCalc : public Calc {
public:
    SomeType PowerMethod() override { 
        Calc::Complex();
        return Calc::target;
    };
};

If your target is to learn OOP then you can use a factory design pattern to create your final calculator based on isSimple condition:

#include <iostream>

class Base 
{
public:

    Base()
    {
        target = 0;
    }

    int target;

    virtual void PowerMethod() = 0;
};

class SimpleCalc : public Base
{
    virtual void PowerMethod() { target = 0; }
};

class ComplexCalc : public Base
{
    virtual void PowerMethod() { target = 1000; }
};

class CalcFactory
{
public:
    virtual Base* createCalc(bool isSimple) 
    {
        if (isSimple)
            return new SimpleCalc();
        else
            return new ComplexCalc();
    }
};

int main()
{
    CalcFactory factory;
    Base * base1 = factory.createCalc(true);
    Base * base2 = factory.createCalc(false);
    
    base1->PowerMethod();
    base2->PowerMethod();

    std::cout << base1->target << std::endl;
    std::cout << base2->target << std::endl;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM