Elegant way to access additional serial ports on Mega without hardcoding?

You can try this, it is far more complex, not tested yet, but would remove the selections from run-time ( smaller code )

//My TMP SerialSelector
template< int i_Number > class SerialSelector;
template<> struct SerialSelector< 0 >{ static inline HardwareSerial &Get( void ){ return Serial; } };  
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)    
  template<> struct SerialSelector< 1 >{ static inline HardwareSerial &Get( void ){ return Serial1; } }; 
  template<> struct SerialSelector< 2 >{ static inline HardwareSerial &Get( void ){ return Serial2; } }; 
  template<> struct SerialSelector< 3 >{ static inline HardwareSerial &Get( void ){ return Serial3; } }; 
#endif

//A rework of your class
template< int i_Number >
  class MGCFA632{

    public:

      MGCFA632( int i_Rate = 9600 ) : _port( SerialSelector< i_Number >::Get() ) 
        { this->_port.begin( i_Rate ); }

    protected:
    private:
      
      HardwareSerial &_port;
};

//And finally a declaration.
MGCFA632< 0 > m_Obj;  //Uses Serial
MGCFA632< 1 > m_Obj;  //Uses Serial1
MGCFA632< 2 > m_Obj;  //Uses Serial2
MGCFA632< 3 > m_Obj;  //Uses Serial3

If you can grasp the SerialSelector class you are on a win ( it is a compile time switch construct )