Home > Software design >  How to access inherited class attribute from a third class?
How to access inherited class attribute from a third class?

Time:09-26

The goal of the code structure below is to be able to store pointers to objects of any class inherited from 'A'.

When I run this code, I get 0 written out, but what I'm trying to access is the 'B' object's 'num' value, which is 1. How can I do that?

As far as I know, when you create an inherited class's object, you create an object of the parent class too automatically. So can I somehow access the parent class object from it's child and set it's class member to match?

See minimal reproducible example below.

Update: Virtual functions solved the problem.

#include <iostream>

class A
{
public:
    int num;

    A()
    {
        num = 0;
    }
};

class B : public A
{
public:
    int num;

    B()
    {
        num = 1;
    }
};

class C 
{
public:
    A* ptr_array[2];

    C()
    {
        ptr_array[0] = new B();
    }

    void print()
    {
        std::cout << ptr_array[0]->num << std::endl;
    }
};

int main()
{
    C* object_c = new C();
    object_c->print();

    return 0;
}

CodePudding user response:

The problem is that you define a member num in A, and another member num in B. So an object of type B has two members called num, and you're leaving it to the compiler to choose which one to use -- which it does, according to logical rules which may be unfamiliar to you.

If you remove the line in num; from the definition of B, the code will work as you intend.

CodePudding user response:

Your array is a red herring. You are only using one pointer. Might just as well have it as a member for the sake of the example.

I suppose you might need something like this (note, untested code).

#include <memory>
#include <iostream>

class A {
  public:
    A() : m_num(0) {} // use this instead of assignment in the c'tor body

    virtual int getNum() { return m_num; } // this is **the** way to use inheritance

    virtual ~A() = default; // required
  private:
    int m_num;
};

class B : public A {
  public:
    B() : m_otherNum(1) {}

    virtual int getNum() { return m_otherNum; } // does something different from A
  private:
    int m_otherNum; // you could also call it m_num, but for clarity I use a different name 
};

class C {
  public:
    C() : m_a (std::make_unique<B>()) {} // note, use this instead of new B

    void print() {
      std::cout << m_a->getNum() << std::endl;
    }

  private:
    std::unique_ptr<A> m_a; // note, use this instead of A* m_a;
};

I have no way of knowing if this is really what you need (or you think you need). This is how inheritance is supposed to be used in object-oriented programming. You can use it in various other ways and produce correct (as far as the language definition is concerned) programs. But if this is the case, then (public) inheritance is likely not the best tool for the job.

  • Related