Search code examples
c++inheritanceoverridingencapsulation

Overrided method calling from base class c++


I have 2 classes as NumberArray and PrimeNumberArray. PrimeNumberArray is subclass of NumberArray These classes have generate methods which generate array with random numbers. And I call these methods in NumberArray class. In main method I create PrimeNumberArray object and call the method "generateAndPrint" which should call PrimeNumberClass's generate method but actually the method is working from base class. Generate method which finds prime numbers is working. I just want to learn how to call it in method from base class.

Base class;

class NumberArray{
protected:
    int* numbers;
    int amount;
public:
    NumberArray(int size = 0){
        amount = size;
        int array[amount];
        numbers = array;
    }
    ~NumberArray(){
        delete[] numbers;
    }
    void generateAndPrint(){
        generate();
        print();
    }
private:
    void generate(){
        int i = 0;
        while (i < amount)
        {
            cout << "a" << endl;
            int rnd = (rand() % 1000) +1;
            numbers[i] = rnd;
            i++;
            
        }
    }
    void print(){
        int i;
        for (i = 0; i < amount; i++)
        {
            cout << numbers[i] << " -> ";
        }
        cout << endl;
    }
};

Subclass;

class PrimeNumberArray: public NumberArray{
public:
    PrimeNumberArray(int size){
        amount = size;
        int array[amount];
        numbers = array; 
    }

    void virtual generate(){
        int i = 0;
        while (i <amount)
        {                   
            int rnd = (rand() % 1000) +1;
            int j;
            int isPrime = 1;
            for(j = 2; j < rnd / 2; j++){
                if(rnd % j == 0){
                    isPrime = 0;
                }
            }
            if(isPrime == 1){
                numbers[i] = rnd;
                i++;
            }
        }
    }
};

Test class;

int main(){
   PrimeNumberArray prime(5);
   prime.generateAndPrint();
}

I tried to make generate method virtual but not works for me.


Solution

  • The code below should get you started:

    • Make generate virtual void generate() in base class, and virtual void generate() override in derived class.
    • Create heap instances of PrimeNumberArray but assign them to NumberArray pointers; you can use smart pointers for this so you don't need to manually free the instances.
    • Then, you can just call whatever virtual methods using the pointer to the base class; the runtime polymorphism will kick in and end up calling the derived class methods.
    • You can do the numbers' management in the base class only; you don't need to duplicate the code in the derived class; just call the base class constructor from the derived class constructor with NumberArray(size).
    • Add a virtual destructor in the base class as well.

    [Demo]

    #include <iostream>  // cout
    #include <memory>  // make_unique, unique_ptr
    
    class NumberArray {
    protected:
        int* numbers;
        int amount;
    public:
        NumberArray(int size = 0) : amount{size}, numbers{ new int[](size) } {}
        virtual ~NumberArray() { delete[] numbers; }    
        void generateAndPrint() {
            generate();
            print();
        }
    private:
        virtual void generate() {
            for (int i = 0; i < amount; i++) {
                std::cout << "a\n";
                int rnd = (rand() % 1000) + 1;
                numbers[i] = rnd;
                i++;
            }
        }
        void print() {
            for (int i = 0; i < amount; i++) {
                std::cout << numbers[i] << " -> ";
            }
            std::cout << "\n";
        }
    };
    
    class PrimeNumberArray: public NumberArray {
    public:
        PrimeNumberArray(int size) : NumberArray(size) {}
    
        virtual void generate() override {
            for (int i = 0; i < amount; ) {                   
                int rnd = (rand() % 1000) + 1;
                bool isPrime = true;
                for (int j = 2; j < rnd / 2; j++) {
                    if (rnd % j == 0) {
                        isPrime = false;
                    }
                }
                if (isPrime) {
                    numbers[i] = rnd;
                    i++;
                }
            }
        }
    };
    
    int main() {
       std::unique_ptr<NumberArray> prime{std::make_unique<PrimeNumberArray>(5)};
       prime->generateAndPrint();
    }