Home > Enterprise >  How to have inherited functions use local variables
How to have inherited functions use local variables

Time:11-01

I want to apply the functions from one class to the private variables from another derived class. I was hoping that this way I could avoid redefining the exact same function multiple times.

I've added an example below.

#include <iostream>

class A {
public:
    void print1();
    void print2();
private:
    int array[3] = {1, 2, 3};
};

class B: public A {
public:
    void print3();
private:
    int array[3] = {4, 5, 6};
};

void A::print1() {
    std::cout << this->array[0] << std::endl;
}

void A::print2() {
    std::cout << this->array[1] << std::endl;
}

void B::print3() {
    print1();
    print2();
    std::cout << this->array[2] << std::endl;
}


int main() {
    B b;
    b.print3(); // Output = 1 2 6, I want = 4 5 6
    return 0;
}

I thought that perhaps defining the array in class A and B as public, so it would get overwritten, would work, but this did not have any effect.

CodePudding user response:

There are two solutions, related to design patterns called "Non-virtual interface" or "Template methods".

Without virtual methods: add a member which will point to the private array:

class A {
  public:
    A() : array(_array) {}
    void print1();
    void print2();
  protected:
    A(int array[3]) : array(array) {}
    int *array;
  private:
    int _array[3] = {1, 2, 3};
};

class B: public A {
  public:
    B() : A(_array) {}
    void print3();
  private:
    int _array[3] = {4, 5, 6};
};

Or add a virtual method, which will return the pointer:

class A {
  public:
    void print1();
    void print2();
  protected:
    virtual int *array() { return _array; };
  private:
    int _array[3] = {1, 2, 3};
};

class B: public A {
  public:
    void print3();
  protected:
    virtual int *array() { return _array; };
  private:
    int _array[3] = {4, 5, 6};
};

In this second solution use array() instead of array in methods (std::cout << this->array()[0] << std::endl; etc.).

CodePudding user response:

If the implementation of print1 and print2 must be in the base class, then you need some form of polymorphic access to the array associated with the object instance.

#include <iostream>

class A {
public:
    void print1();
    void print2();

private:
    virtual const int* getArray() const { return array; };
    int array[3] = {1, 2, 3};
};

class B: public A {
public:
    void print3();
private:
    virtual const int* getArray() const { return array; };
    int array[3] = {4, 5, 6};
};

void A::print1() {
    std::cout << this->getArray()[0] << std::endl;
}

void A::print2() {
    std::cout << this->getArray()[1] << std::endl;
}

void B::print3() {
    print1();
    print2();
    std::cout << this->getArray()[2] << std::endl;
}


int main() {
    B b;
    b.print3(); // Outputs 4 5 6
    return 0;
}

CodePudding user response:

Inheritance does not work like this, you are close to get it, but your design needs a small change. What you need to do is to change your print1 and print2 functions, to receive the argument you want to print:

class A {
public:
    void print1(int num);
    ...
private:
    int array[3] = {1, 2, 3};
};

void A::print1(int num) {
    std::cout << num << std::endl;
}

Then you call the print1 and print2 functions with the int you are interested:

void B::print3() {
    print1(array[0]);
    print2(array[1]);
    std::cout << this->array[2] << std::endl;
}

This will call those functions in your class B with the values stored in the "override" array, and you will have the output you are looking for:

int main() {
    B b;
    b.print3(); // Output = 4 5 6
    return 0;
}
  • Related