Issues with overloading a constructor for a class in a separate .cpp file

Hello, I am currently coding a phoneme-based servo driver for my arduino Mega, which features a class called PhonemeBlock stored on its own .cpp and .h files. However, the project fails to compile, throwing this error:

Temp\cc3zkw9M.ltrans0.ltrans.o: In function `global constructors keyed to 65535_0_Animation.cpp.o.2214':<artificial>:(.text.startup+0x9a): undefined reference to `PhonemeBlock::PhonemeBlock()

This is confusing because I have 3 defined constructors for the PhonemeBlock class:

PhonemeBlock::PhonemeBlock(String x, float st, float et){
starttime = st;
endtime= et;
name = x;
id = phonemeID(x);
jogspeed = 200;
  }


  PhonemeBlock::PhonemeBlock(String x, float st, float et, int js){
starttime = st;
endtime= et;
name = x;
id = phonemeID(x);
jogspeed = js;
  }

PhonemeBlock::PhonemeBlock(){
  name = "M";
  id = phonemeID(name);
  jogspeed = 200;
  starttime = 0.0;
  endtime = 0.0;
}

The header file for this section looks like this:

#ifndef ANIMATION_H
#define ANIMATION_H
#include "Posing.h"

class PhonemeBlock{
  public:
  String name;
  byte id;
  float starttime;
  float endtime;
  int jogspeed;
  PhonemeBlock();
  PhonemeBlock(String x, float st, float et, int js);
  PhonemeBlock(String x, float st, float et);
};

#endif

Is the compiler capable of overloading class definitions like this? If so, what's my mistake here?

Yes.

The big mistake is not showing a complete sketch that demonstrates the problem. Because you've done something wrong in the code you haven't shown us, and we can't try it ourselves to see where the problem is.

How do I know this? Simple; the following trivial example that I just threw together compiles cleanly. And you can test that for yourself because I included the full sketch.

test.ino

#include "TestClass.h"

TestClass ex1;
TestClass ex2("Hello");
TestClass ex3(123);

void setup() {
   Serial.begin(115200);
   ex1.show();
   ex2.show();
   ex3.show();
}

void loop() {
}

TestClass.h

#pragma once
#include <Arduino.h>

class TestClass {
 public:
   TestClass();
   TestClass(String str);
   TestClass(int i);
   void show(void);
 private:
   String m_str;
   int m_i;
};

TestClass.cpp

#include "TestClass.h"

TestClass::TestClass() {
   m_str = "";
   m_i = 0;
}

TestClass::TestClass(String str) {
   m_str = str;
   m_i = 0;
}

TestClass::TestClass(int i) {
   m_str = "";
   m_i = i;
}

void TestClass::show(void) {
   Serial.print("str=");
   Serial.println(m_str);
   Serial.print("i=");
   Serial.println(m_i);
}

I avoided including the whole sketch because it is split across 4 files, some over 100 lines.

The main use for this class is in a routine defined in a file called Serialcommands, which has the "includes":

#include "Serialcommands.h"
#include "Animation.h"
#include <Arduino.h>
#include <Servo.h>

bool stringComplete = false;  // whether the string is complete
String inputString = "";      // a String to hold incoming data
const int MAX_ANIMATION_LENGTH =  100;
PhonemeBlock animation[MAX_ANIMATION_LENGTH];

This class is referenced in the function

void AnimationSet(String x){
  stored_anim_length = 0; // reset animation length counter
String y = x;
while(y.indexOf(",") != -1){
y = y.substring(y.indexOf("\"")+1); // chops off first quote
String ph = y.substring(0,y.indexOf("\"")); // returns phoneme
y = y.substring(y.indexOf("\"")+1); // chops off second quote
float starttime = y.substring(0, y.indexOf(",")).toFloat();
y = y.substring(y.indexOf(",")+1); // chops off start time
float endtime = y.substring(0, y.indexOf("\n")).toFloat();

animation[stored_anim_length] = PhonemeBlock(ph, starttime, endtime); // add animation block
stored_anim_length++;

}
  return;
}

Which parses an incoming string formatted like so:

TH,0.000,0.079
IH,0.079,0.158
S,0.158,0.237
SIL,0.237,0.316

over serial and updates the animation[] array with each incoming PhonemeBlock.
I intended to instantiate a new Phoneme block each cycle of the While loop, and then set the corresponding index of animation[] equal to that, to build a sequence of PhonemeBlock objects.
Do I need to add any special code to allow my class to be used in an array?
[edit]: the full error:

C:\Users\R\AppData\Local\Temp\ccq2BvFx.ltrans0.ltrans.o: In function `global constructors keyed to 65535_0_Animation.cpp.o.2214':
<artificial>:(.text.startup+0x9a): undefined reference to `PhonemeBlock::PhonemeBlock()'
C:\Users\R\AppData\Local\Temp\ccq2BvFx.ltrans0.ltrans.o: In function `AnimationSet':
C:\Users\R\Documents\GitHub\ArduinoPythonPoser\Arduino\Poser/Serialcommands.cpp:75: undefined reference to `PhonemeBlock::PhonemeBlock(String, float, float)'
collect2.exe: error: ld returned 1 exit status

Resolved! I forgot to include the Animation.h file in the Animation.cpp file!

New:

#include "Animation.h"
#include "Posing.h"
#include <Arduino.h>

PhonemeBlock::PhonemeBlock(){
  name = "M";
  id = phonemeID(name);
  jogspeed = 200;
  starttime = 0.0;
  endtime = 0.0;
}
/// etc....

QED