0

I have two structs pins1_t & pins2_t with the same field names but different values. pins2_t is derived from pins1_t

namespace pins {
    struct pins1_t {
        int A = 1;
        int B = 2;
        int C = 3;
        int D = 4;
    };

    struct pins2_t : pins1_t {
        int A = 6;
        int B = 7;
        int C = 8;
        int D = 9;
    };
};

I'm trying to access the values from pins2_t by referencing via the base struct, but without any success.

pins::pins1_t pins1;
pins::pins2_t pins2;

pins::pins1_t* pPins;
pins::pins1_t* pPins2;

pPins = &pins1;
pPins2 = &pins2;

print("Pins %d, Pins2 %d, PPins %d, PPins2 %d", pins1.A, pins2.A, pPins->A, pPins2->A);
The output is: "Pins 1, Pins2 6, PPins 1, PPins2 1"
But should be: "Pins 1, Pins2 6, PPins 1, PPins2 6"

Even if I try pins::pins2_t* pPins2, so I reference the derived class pointer with the derived class I get the value of the base class :/

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Manuel
  • 293
  • 2
  • 17

3 Answers3

1

The members in your derived class shadow the members in your base class. This is almost never what you want (since, as you noticed, it doesn’t work).

Since these are just variables anyway, there’s no need to shadow the declarations in the child class. Just initialise the base class members:

struct pins1_t {
    int A = 1;
    int B = 2;
    int C = 3;
    int D = 4;
};

struct pins2_t : pins1_t {
    pins2_t() : pins1_t{6, 7, 8, 9} {}
};

(Alternatively, you could employ runtime polymorphism via virtual functions as suggested by interjay, but there’s currently nothing in your question to suggest that this is necessary; and in the absence of a compelling reason it’s over-engineering.)

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 2
    OP might also be interested by just `struct pins_t {int A; int B; int c; int D;}; const pins_t pins1{1, 2, 3, 4}; const pins_t pins2{6, 7, 8, 9};`... – Jarod42 Mar 09 '21 at 11:22
  • Thx, that works for me - unfortunately you can't make the values const (so they are stored in flash) but that wasn't my question, although would be a nice additional feature. – Manuel Mar 09 '21 at 13:05
  • @Manuel Why can’t you make the values const? – Konrad Rudolph Mar 09 '21 at 13:06
0

I'm trying to access the values from pins2_t by referencing via the base struc

You can only access the base sub object's members through the base sub object. You cannot access the members of the derived class. Thus, you cannot achieve what you're trying to do.

eerorika
  • 232,697
  • 12
  • 197
  • 326
0

It seems you need to double-check your solution. At least this part:

Even if I try pins::pins2_t* pPins2, so I reference the derived class pointer with the derived class I get the value of the base class :/

This code works for me (Mac OS, g++ 4.2.1 compiler):

  pins1_t pins1;
  pins2_t pins2;

  pins1_t* pPins;
  pins2_t* pPins2; // <-- pointer type fixed here

  pPins = &pins1;
  pPins2 = &pins2;

  printf("Pins %d, Pins2 %d, PPins %d, PPins2 %d", pins1.A, pins2.A, pPins->A, pPins2->A);

The output is the same as it's written in your "should be" part:

  Pins 1, Pins2 6, PPins 1, PPins2 6

The simpliest way is to use dynamic_cast. But you need to define at least one virtual function for this way to work. See C++ inheritance downcasting

From the other side, in order to access the derived class fields using pointer to the base class WITHOUT using standard dynamic_cast way, one could use static_cast or even reinterpret_cast. But it seems to be a dirty hack. Don't use reinterpret_cast unless you know what you're doing :)

SGrebenkin
  • 572
  • 4
  • 10
  • The pointer type in OP’s code is almost certainly *intentional*. Apart from that I don’t understand why you make reference to `dynamic_cast`. It doesn’t fit either the question or your code. – Konrad Rudolph Mar 09 '21 at 11:58