1

I'm working on the core for a family of microprocessor units based off of the ATMEGA328P. I have a base class and two derived classes that I need to store mixed together in an array. I have the following:

// base class
class Channel {
   virtual String ReturnValuesAsString();
   virtual void ResetValues();
   ...
}

// derived class
class DigitalChannel : Channel {
   String ReturnValuesAsString() override;
   void ResetValues() override;
}

// derived class
class AnalogChannel : Channel {
   String ReturnValuesAsString() override;
   void ResetValues() override;
}

On my other object, I have the following:

class Input {
   Channel *Channels; //array of channels

   Input(int totalPossibleChannels, Channel *channels[]) {

      this->Channels = new Channel[totalPossibleChannels];

      // pseudocoded for loop using 'chanIndex' iterator to keep it short on this post
      for channel in channels {
         this->Channels[chanIndex] = *channels[chanIndex];
      }
   }
}

I initialize the input as follows:

DigitalChannel digitalChannel00 = DigitalChannel();
DigitalChannel digitalChannel01 = DigitalChannel();

Channel *digitalInputChannelsInput0[] = { &digitalChannel00, &digitalChannel01 };

Input input0 = Input(2, digitalInputChannelsInput0);

My problem is when I reference any of the channels similar to the following:

input0.Channels[0].ReturnValuesAsString();

I get the base class implementation of that method rather than the derived implementation. I've read a bit about this and it appears that this is caused by object slicing distilling them down to the base class. Is there another way that I can handle this? I don't have access to smart pointers or vectors on this platform (arduino is a limited port of c++). Thanks in advance! I'm open to any suggestions as well.

Update: Marking this as solved, but I wanted to add some more context to help others later

Here is the new structure:

class Input {
   Channel **Channels; //array of channel pointers

   Input(int totalPossibleChannels, Channel *channels[]) {

      this->Channels = new Channel *[totalPossibleChannels];

      // pseudocoded for loop using 'chanIndex' iterator to keep it short on this post
      for channel in channels {
         this->Channels[chanIndex] = channels[chanIndex];
      }
   }
}

I initialize the input as follows:

DigitalChannel digitalChannel00 = DigitalChannel();
DigitalChannel digitalChannel01 = DigitalChannel();

Channel *digitalInputChannelsInput0[] = { &digitalChannel00, &digitalChannel01 };

Input input0 = Input(2, digitalInputChannelsInput0);

1 Answer 1

1

you are maintaining an array of channel obejcts.
For virtual function to work you need to maintain either pointer of base class type or a reference.

Channel *Channels;

creates an array of Channel obejcts. You need to create an array of pointer/reference to channel object i.e.

Channel **Channels;

Change the program accordingly to use pointer instead of object of channel type.

Sign up to request clarification or add additional context in comments.

2 Comments

Would I then use input0.Channels[0]->ReturnValuesAsString(); from then on once the pointer array is fixed?
@PhillipMcMullen yes. that is how you access members using pointer to a object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.