Trouble with inheriting from Print

In the display.h file the line at 59 is:

class  ssd1963 //: public Print

That class is instantiated in the .ino file at line 29 with:

ssd1963 tft(RS, WR, CS, RST); 

If the class definition is changed so that it inherits from Print like this:

class  ssd1963 : public Print

Then the instantiation in the .ino file fails with:

Arduino: 1.8.19 (Windows 10), TD: 1.57, Board: "Teensy 4.0, Serial, 600 MHz, Faster, US English"
Teensy40_800x400:27: error: cannot declare variable 'tft' to be of abstract type 'ssd1963'
 ssd1963 tft(RS, WR, CS, RST); 
         ^
In file included from C:\Users\Mike\Desktop\Teensy40_800x400\Teensy40_800x400.ino:1:0:
C:\Users\Mike\Desktop\Teensy40_800x400\display.h:59:8: note:   because the following virtual functions are pure within 'ssd1963':
 class  ssd1963 : public Print
        ^
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/Stream.h:24:0,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/HardwareSerial.h:115,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/WProgram.h:46,
                 from C:\Users\Mike\AppData\Local\Temp\arduino_build_191811\pch\Arduino.h:6:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/Print.h:58:17: note: 	virtual size_t Print::write(uint8_t)
  virtual size_t write(uint8_t b) = 0;
                 ^
Multiple libraries were found for "gfxfont.h"
 Used: C:\Users\Mike\Documents\Arduino\libraries\Adafruit_GFX_Library
 Not used: C:\Users\Mike\Documents\Arduino\libraries\arduino_652672
 Not used: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\ssd1351
cannot declare variable 'tft' to be of abstract type 'ssd1963' 
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

So, my question is, what am I doing wrong and how can I fix this?

Teensy40_800x480.ino

#include "display.h"
#include <C:\Users\Mike\Documents\Arduino\libraries\Adafruit_GFX_Library\Fonts\FreeMono24pt7b.h>

#define RS  26
#define WR  27
#define CS  25
#define RST 28
#define BL_CTL  21
#define TFT_DC 9
#define TFT_CS 10

#define DWIDTH 800
#define DHEIGHT 480
#define DELTA_C 21
#define DELTA_R 30
#define BASE_R 22

uint32_t c = 0;
uint32_t mask = 0;
int16_t cnt = 0;
bool _cp437 = false;
uint8_t w = 0;
uint8_t h = 0;

GFXfont  *gfxFont;

ssd1963 tft(RS, WR, CS, RST); 

  void setup()
{
  setFont(&FreeMono24pt7b);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(BL_CTL, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  digitalWrite(BL_CTL, HIGH);
  digitalWriteFast(LED_BUILTIN, LOW);
  tft.print(300, 300, "abc", WHITE, BLACK);
  tft.startDisplay();
  tft.setColor(BLACK);
  tft.fillRect(0, 0, 799, 479);

  struct GFXglyph
  {
    uint16_t bitmapOffset; ///< Pointer into GFXfont->bitmap
    uint8_t width;         ///< Bitmap dimensions in pixels
    uint8_t height;        ///< Bitmap dimensions in pixels
    uint8_t xAdvance;      ///< Distance to advance cursor (x axis)
    int8_t xOffset;        ///< X dist from cursor pos to UL corner
    int8_t yOffset;        ///< Y dist from cursor pos to UL corner
  };

  for (int i = 0; i < 26; i++)
  {
    drawChar(0 + 30 * i, 100, (unsigned char)'a' + i, WHITE, BLACK, 1, 1);
    drawChar(0 + 30 * i, 150, (unsigned char)'A' + i, WHITE, BLACK, 1, 1);
    if (i < 17)
      drawChar(0 + 30 * i, 200, (unsigned char)'0' + i, WHITE, BLACK, 1, 1);
  }

  // dump(31);
}

/************************************************************************************/
GFXglyph *pgm_read_glyph_ptr(const GFXfont *gfxFont, uint8_t c)
{
  return gfxFont->glyph + c;
}

/************************************************************************************/
uint8_t *pgm_read_bitmap_ptr(const GFXfont *gfxFont)
{
#ifdef __AVR__
  return (uint8_t *)pgm_read_pointer(&gfxFont->bitmap);
#else
  // expression in __AVR__ section generates "dereferencing type-punned pointer
  // will break strict-aliasing rules" warning In fact, on other platforms (such
  // as STM32) there is no need to do this pointer magic as program memory may
  // be read in a usual way So expression may be simplified
  return gfxFont->bitmap;
#endif //__AVR__
}

/************************************************************************************/
void drawChar(int16_t x, int16_t y, unsigned char c,
              uint16_t fg, uint16_t bg, uint16_t size_x,
              uint16_t size_y)
{
  // Custom font
  {
    // Character is assumed previously filtered by write() to eliminate
    // newlines, returns, non-printable characters, etc.  Calling
    // drawChar() directly with 'bad' characters of font may cause mayhem!
    c -= (uint8_t)pgm_read_byte(&gfxFont->first);

    GFXglyph *glyph = pgm_read_glyph_ptr(gfxFont, c);
    uint8_t *bitmap = pgm_read_bitmap_ptr(gfxFont);
    uint16_t bo = pgm_read_word(&glyph->bitmapOffset);

    w = pgm_read_byte(&glyph->width);
    h = pgm_read_byte(&glyph->height);

    int8_t xo = pgm_read_byte(&glyph->xOffset),
           yo = pgm_read_byte(&glyph->yOffset);
    uint8_t xx, yy, bits = 0, bit = 0;
    int16_t xo16 = 0, yo16 = 0;
    if (size_x > 1 || size_y > 1)
    {
      xo16 = xo;
      yo16 = yo;
    }

    // Todo: Add character clipping here

    // NOTE: THERE IS NO 'BACKGROUND' COLOR OPTION ON CUSTOM FONTS.
    // THIS IS ON PURPOSE AND BY DESIGN.  The background color feature
    // has typically been used with the 'classic' font to overwrite old
    // screen contents with new data.  This ONLY works because the
    // characters are a uniform size; it's not a sensible thing to do with
    // proportionally-spaced fonts with glyphs of varying sizes (and that
    // may overlap).  To replace previously-drawn text when using a custom
    // font, use the getTextBounds() function to determine the smallest
    // rectangle encompassing a string, erase the area with fillRect(),
    // then draw new text.  This WILL infortunately 'blink' the text, but
    // is unavoidable.  Drawing 'background' pixels will NOT fix this,
    // only creates a new set of problems.  Have an idea to work around
    // this (a canvas object type for MCUs that can afford the RAM and
    // displays supporting setAddrWindow() and pushColors()), but haven't
    // implemented this yet.
    //Serial.println("h");

    //    startWrite();
    for (yy = 0; yy < h; yy++)
    {
      for (xx = 0; xx < w; xx++)
      {
        if (!(bit++ & 7))
        {
          bits = pgm_read_byte(&bitmap[bo++]);
        }
        if (bits & 0x80)
        {
          if (size_x == 1 && size_y == 1)
          {
            tft.drawPixel(x + xo + xx, y + yo + yy, fg);
          }
          else
          {
            tft.fillRect(x + (xo16 + xx) * size_x, y + (yo16 + yy) * size_y, size_x, size_y, fg);
          }
        }
        bits <<= 1;
      }
    }
    //   endWrite();

  } // End classic vs custom font
}

void dump(int n)
{
  Serial.print(FreeMono24pt7bGlyphs[n].bitmapOffset); Serial.print(" ");
  Serial.print(FreeMono24pt7bGlyphs[n].width); Serial.print(" ");
  Serial.print(FreeMono24pt7bGlyphs[n].height); Serial.print(" ");
  Serial.print(FreeMono24pt7bGlyphs[n].xAdvance); Serial.print(" ");
  Serial.print(FreeMono24pt7bGlyphs[n].xOffset); Serial.print(" ");
  Serial.print(FreeMono24pt7bGlyphs[n].yOffset);
}

void setFont(const GFXfont *f)
{
  if (f)            // Font struct pointer passed in?
  {
    if (!gfxFont)  // And no current font struct?
    {
      // Switching from classic to new font behavior.
      // Move cursor pos down 6 pixels so it's on baseline.
      //      cursor_y += 6;
    }
  }
  else if (gfxFont) // NULL passed.  Current font struct defined?
  {
    // Switching from new to classic font behavior.
    // Move cursor pos up 6 pixels so it's at top-left of char.
    //    cursor_y -= 6;
  }
  gfxFont = (GFXfont *)f;
}



void loop()
{
}

display.cpp

#include "Arduino.h"
#include "display.h"
#include <mine.h>

void _swap_int16_t(int16_t &a, int16_t &b)
{
  int16_t t = a;
  a = b;
  b = t;
}

ssd1963:: ssd1963()
{
}

ssd1963:: ssd1963(int RS, int WR, int CS, int RST)
{
  pinMode(DB_0, OUTPUT);
  pinMode(DB_1, OUTPUT);
  pinMode(DB_2, OUTPUT);
  pinMode(DB_3, OUTPUT);
  pinMode(DB_4, OUTPUT);
  pinMode(DB_5, OUTPUT);
  pinMode(DB_6, OUTPUT);
  pinMode(DB_7, OUTPUT);

  pinMode(DB_8, OUTPUT);
  pinMode(DB_9, OUTPUT);
  pinMode(DB_10, OUTPUT);
  pinMode(DB_11, OUTPUT);
  pinMode(DB_12, OUTPUT);
  pinMode(DB_13, OUTPUT);
  pinMode(DB_14, OUTPUT);
  pinMode(DB_15, OUTPUT);

  pinMode(RS, OUTPUT);
  pinMode(WR, OUTPUT);
  pinMode(CS, OUTPUT);
  pinMode(RST, OUTPUT);
  digitalWriteFast(B_RST, HIGH);
  B_RS = RS;
  B_WR = WR;
  B_CS = CS;
  B_RST = RST;
}

void  ssd1963::tft_Write_Bus16(uint16_t data)
{
  digitalWriteFast(B_RS, HIGH);
  ((data & 0x8000) != 0) ? digitalWriteFast(DB_15, HIGH) : digitalWriteFast(DB_15, LOW);
  ((data & 0x4000) != 0) ? digitalWriteFast(DB_14, HIGH) : digitalWriteFast(DB_14, LOW);
  ((data & 0x2000) != 0) ? digitalWriteFast(DB_13, HIGH) : digitalWriteFast(DB_13, LOW);
  ((data & 0x1000) != 0) ? digitalWriteFast(DB_12, HIGH) : digitalWriteFast(DB_12, LOW);
  ((data & 0x0800) != 0) ? digitalWriteFast(DB_11, HIGH) : digitalWriteFast(DB_11, LOW);
  ((data & 0x0400) != 0) ? digitalWriteFast(DB_10, HIGH) : digitalWriteFast(DB_10, LOW);
  ((data & 0x0200) != 0) ? digitalWriteFast(DB_9, HIGH) : digitalWriteFast(DB_9, LOW);
  ((data & 0x0100) != 0) ? digitalWriteFast(DB_8, HIGH) : digitalWriteFast(DB_8, LOW);
  ((data & 0x80) != 0) ? digitalWriteFast(DB_7, HIGH) : digitalWriteFast(DB_7, LOW);
  ((data & 0x40) != 0) ? digitalWriteFast(DB_6, HIGH) : digitalWriteFast(DB_6, LOW);
  ((data & 0x20) != 0) ? digitalWriteFast(DB_5, HIGH) : digitalWriteFast(DB_5, LOW);
  ((data & 0x10) != 0) ? digitalWriteFast(DB_4, HIGH) : digitalWriteFast(DB_4, LOW);
  ((data & 0x08) != 0) ? digitalWriteFast(DB_3, HIGH) : digitalWriteFast(DB_3, LOW);
  ((data & 0x04) != 0) ? digitalWriteFast(DB_2, HIGH) : digitalWriteFast(DB_2, LOW);
  ((data & 0x02) != 0) ? digitalWriteFast(DB_1, HIGH) : digitalWriteFast(DB_1, LOW);
  ((data & 0x01) != 0) ? digitalWriteFast(DB_0, HIGH) : digitalWriteFast(DB_0, LOW);

  digitalWriteFast(B_WR, LOW);
  digitalWriteFast(B_WR, HIGH);
}

void  ssd1963::tft_Write_Bus(char ch, char cl)
{
  ((ch & 0x80) != 0) ? digitalWriteFast(DB_15, HIGH) : digitalWriteFast(DB_15, LOW);
  ((ch & 0x40) != 0) ? digitalWriteFast(DB_14, HIGH) : digitalWriteFast(DB_14, LOW);
  ((ch & 0x20) != 0) ? digitalWriteFast(DB_13, HIGH) : digitalWriteFast(DB_13, LOW);
  ((ch & 0x10) != 0) ? digitalWriteFast(DB_12, HIGH) : digitalWriteFast(DB_12, LOW);
  ((ch & 0x08) != 0) ? digitalWriteFast(DB_11, HIGH) : digitalWriteFast(DB_11, LOW);
  ((ch & 0x04) != 0) ? digitalWriteFast(DB_10, HIGH) : digitalWriteFast(DB_10, LOW);
  ((ch & 0x02) != 0) ? digitalWriteFast(DB_9, HIGH) : digitalWriteFast(DB_9, LOW);
  ((ch & 0x01) != 0) ? digitalWriteFast(DB_8, HIGH) : digitalWriteFast(DB_8, LOW);
  ((cl & 0x80) != 0) ? digitalWriteFast(DB_7, HIGH) : digitalWriteFast(DB_7, LOW);
  ((cl & 0x40) != 0) ? digitalWriteFast(DB_6, HIGH) : digitalWriteFast(DB_6, LOW);
  ((cl & 0x20) != 0) ? digitalWriteFast(DB_5, HIGH) : digitalWriteFast(DB_5, LOW);
  ((cl & 0x10) != 0) ? digitalWriteFast(DB_4, HIGH) : digitalWriteFast(DB_4, LOW);
  ((cl & 0x08) != 0) ? digitalWriteFast(DB_3, HIGH) : digitalWriteFast(DB_3, LOW);
  ((cl & 0x04) != 0) ? digitalWriteFast(DB_2, HIGH) : digitalWriteFast(DB_2, LOW);
  ((cl & 0x02) != 0) ? digitalWriteFast(DB_1, HIGH) : digitalWriteFast(DB_1, LOW);
  ((cl & 0x01) != 0) ? digitalWriteFast(DB_0, HIGH) : digitalWriteFast(DB_0, LOW);

  digitalWriteFast(B_WR, LOW);
  digitalWriteFast(B_WR, HIGH);
}

void ssd1963::print(int16_t x, int16_t y, String text, uint16_t fg, uint16_t bg)
{
  int16_t len = text.length();
  Serial.println(len, HEX);
}

void  ssd1963::tft_Write_DATA(char VL)
{
  digitalWriteFast(B_RS, HIGH);
  tft_Write_Bus(0x00, VL);

}

void  ssd1963::tft_Write_DATA(char VH, char VL)
{
  digitalWriteFast(B_RS, HIGH);
  tft_Write_Bus(VH, VL);
}

void  ssd1963::tft_Write_COMMAND(char VL)
{
  digitalWriteFast(B_RS, LOW);
  tft_Write_Bus(0x00, VL);

}

void  ssd1963::startDisplay(void)
{

  digitalWriteFast(B_RST, LOW);
  delay(10);

  digitalWriteFast(B_RST, HIGH);
  delay(10);

  digitalWriteFast(B_CS, LOW);

  tft_Write_COMMAND(0xE2);    //PLL multiplier, set PLL clock to 120M
  tft_Write_DATA(0x1E);   //N=0x36 for 6.5M, 0x23 for 10M crystal
  tft_Write_DATA(0x02);
  tft_Write_DATA(0x54);
  tft_Write_COMMAND(0xE0);    //PLL enable
  tft_Write_DATA(0x01);
  delay(10);
  tft_Write_COMMAND(0xE0);
  tft_Write_DATA(0x03);
  delay(10);
  tft_Write_COMMAND(0x01);    //Software reset
  delay(50);
  tft_Write_COMMAND(0xE6);    //PLL setting for PCLK, depends on resolution
  tft_Write_DATA(0x03);
  tft_Write_DATA(0xFF);
  tft_Write_DATA(0xFF);

  tft_Write_COMMAND(0xB0);    //tft SPECIFICATION
  tft_Write_DATA(0x24);
  tft_Write_DATA(0x00);
  tft_Write_DATA(0x03);   //Set HDP 799
  tft_Write_DATA(0x1F);
  tft_Write_DATA(0x01);   //Set VDP 479
  tft_Write_DATA(0xDF);
  tft_Write_DATA(0x00);

  tft_Write_COMMAND(0xB4);    //HSYNC
  tft_Write_DATA(0x03);   //Set HT  928
  tft_Write_DATA(0xA0);
  tft_Write_DATA(0x00);   //Set HPS 46
  tft_Write_DATA(0x2E);
  tft_Write_DATA(0x30);   //Set HPW 48
  tft_Write_DATA(0x00);   //Set LPS 15
  tft_Write_DATA(0x0F);
  tft_Write_DATA(0x00);

  tft_Write_COMMAND(0xB6);    //VSYNC
  tft_Write_DATA(0x02);   //Set VT  525
  tft_Write_DATA(0x0D);
  tft_Write_DATA(0x00);   //Set VPS 16
  tft_Write_DATA(0x10);
  tft_Write_DATA(0x10);   //Set VPW 16
  tft_Write_DATA(0x00);   //Set FPS 8
  tft_Write_DATA(0x08);

  tft_Write_COMMAND(0xBA);
  tft_Write_DATA(0x0F);   //GPIO[3:0] out 1

  tft_Write_COMMAND(0xB8);
  tft_Write_DATA(0x07);   //GPIO3=input, GPIO[2:0]=output
  tft_Write_DATA(0x01);   //GPIO0 normal

  tft_Write_COMMAND(0x36);    //Rotation
  //tft_Write_DATA(0x22);
  tft_Write_DATA(0x08);

  tft_Write_COMMAND(0xF0);    //pixel data interface
  tft_Write_DATA(0x03);   // 011 16-bit (565 format)

  delay(10);

  tft_Write_COMMAND(0x29);    //display on

  tft_Write_COMMAND(0xBE);    //set PWM for B/L
  tft_Write_DATA(0x06);
  tft_Write_DATA(0xf0);
  tft_Write_DATA(0x01);
  tft_Write_DATA(0xf0);
  tft_Write_DATA(0x00);
  tft_Write_DATA(0x00);

  tft_Write_COMMAND(0xd0);
  tft_Write_DATA(0x0d);

  tft_Write_COMMAND(0x2C);

  digitalWriteFast(B_CS, HIGH);
}

void  ssd1963::setColor(byte r, byte g, byte b)
{
  fch = ((r & 248) | g >> 5);
  fcl = ((g & 28) << 3 | b >> 3);
}

void  ssd1963::setColor(uint16_t color)
{
  byte r = (color & 0xF800) >> 11;
  byte g = (color & 0x07E0) >> 5;
  byte b = color & 0x001F;

  r = (r * 255) / 31;
  g = (g * 255) / 63;
  b = (b * 255) / 31;
  setColor(r, g, b);
}

void  ssd1963::setBackColor(byte r, byte g, byte b)
{
  bch = ((r & 248) | g >> 5);
  bcl = ((g & 28) << 3 | b >> 3);
}

void  ssd1963::setBackColor(uint16_t bg)
{
  byte r = (bg & 0xF800) >> 11;
  byte g = (bg & 0x07E0) >> 5;
  byte b = bg & 0x001F;

  r = (r * 255) / 31;
  g = (g * 255) / 63;
  b = (b * 255) / 31;
  setBackColor(r, g, b);
}

void  ssd1963::setXY(word x1, word y1, word x2, word y2)
{

  tft_Write_COMMAND(0x2a);
  tft_Write_DATA(x1 >> 8);
  tft_Write_DATA(x1);
  tft_Write_DATA(x2 >> 8);
  tft_Write_DATA(x2);
  tft_Write_COMMAND(0x2b);
  tft_Write_DATA(y1 >> 8);
  tft_Write_DATA(y1);
  tft_Write_DATA(y2 >> 8);
  tft_Write_DATA(y2);
  tft_Write_COMMAND(0x2c);

}


void  ssd1963::_fast_fill_16(int ch, int cl, long pix)
{
  long blocks;

  ((ch & 0x80) != 0) ? digitalWriteFast(DB_15, HIGH) : digitalWriteFast(DB_15, LOW);
  ((ch & 0x40) != 0) ? digitalWriteFast(DB_14, HIGH) : digitalWriteFast(DB_14, LOW);
  ((ch & 0x20) != 0) ? digitalWriteFast(DB_13, HIGH) : digitalWriteFast(DB_13, LOW);
  ((ch & 0x10) != 0) ? digitalWriteFast(DB_12, HIGH) : digitalWriteFast(DB_12, LOW);
  ((ch & 0x08) != 0) ? digitalWriteFast(DB_11, HIGH) : digitalWriteFast(DB_11, LOW);
  ((ch & 0x04) != 0) ? digitalWriteFast(DB_10, HIGH) : digitalWriteFast(DB_10, LOW);
  ((ch & 0x02) != 0) ? digitalWriteFast(DB_9, HIGH) : digitalWriteFast(DB_9, LOW);
  ((ch & 0x01) != 0) ? digitalWriteFast(DB_8, HIGH) : digitalWriteFast(DB_8, LOW);
  ((cl & 0x80) != 0) ? digitalWriteFast(DB_7, HIGH) : digitalWriteFast(DB_7, LOW);
  ((cl & 0x40) != 0) ? digitalWriteFast(DB_6, HIGH) : digitalWriteFast(DB_6, LOW);
  ((cl & 0x20) != 0) ? digitalWriteFast(DB_5, HIGH) : digitalWriteFast(DB_5, LOW);
  ((cl & 0x10) != 0) ? digitalWriteFast(DB_4, HIGH) : digitalWriteFast(DB_4, LOW);
  ((cl & 0x08) != 0) ? digitalWriteFast(DB_3, HIGH) : digitalWriteFast(DB_3, LOW);
  ((cl & 0x04) != 0) ? digitalWriteFast(DB_2, HIGH) : digitalWriteFast(DB_2, LOW);
  ((cl & 0x02) != 0) ? digitalWriteFast(DB_1, HIGH) : digitalWriteFast(DB_1, LOW);
  ((cl & 0x01) != 0) ? digitalWriteFast(DB_0, HIGH) : digitalWriteFast(DB_0, LOW);

  blocks = pix / 16;
  for (int i = 0; i < blocks; i++)
  {

    digitalWriteFast(B_WR, LOW); digitalWriteFast(B_WR, HIGH);
    digitalWriteFast(B_WR, LOW); digitalWriteFast(B_WR, HIGH);
    digitalWriteFast(B_WR, LOW); digitalWriteFast(B_WR, HIGH);
    digitalWriteFast(B_WR, LOW); digitalWriteFast(B_WR, HIGH);
    digitalWriteFast(B_WR, LOW); digitalWriteFast(B_WR, HIGH);
    digitalWriteFast(B_WR, LOW); digitalWriteFast(B_WR, HIGH);
    digitalWriteFast(B_WR, LOW); digitalWriteFast(B_WR, HIGH);
    digitalWriteFast(B_WR, LOW); digitalWriteFast(B_WR, HIGH);
    digitalWriteFast(B_WR, LOW); digitalWriteFast(B_WR, HIGH);
    digitalWriteFast(B_WR, LOW); digitalWriteFast(B_WR, HIGH);
    digitalWriteFast(B_WR, LOW); digitalWriteFast(B_WR, HIGH);
    digitalWriteFast(B_WR, LOW); digitalWriteFast(B_WR, HIGH);
    digitalWriteFast(B_WR, LOW); digitalWriteFast(B_WR, HIGH);
    digitalWriteFast(B_WR, LOW); digitalWriteFast(B_WR, HIGH);
    digitalWriteFast(B_WR, LOW); digitalWriteFast(B_WR, HIGH);
    digitalWriteFast(B_WR, LOW); digitalWriteFast(B_WR, HIGH);
  }

  if ((pix % 16) != 0)
    for (int i = 0; i < (pix % 16); i++)
    {
      digitalWriteFast(B_WR, LOW); digitalWriteFast(B_WR, HIGH);
    }
}

void ssd1963::fillRect(int16_t x1, int16_t y1, int16_t x2, int16_t y2)
{
  uint16_t temp;
  if (x1 > x2)
  {
    temp = x1;
    x1 = x2;
    x2 = temp;
  }
  if (y1 > y2)
  {
    temp = y1;
    y1 = y2;
    y2 = temp;
  }

  digitalWriteFast(B_CS, LOW);
  setXY(x1, y1, x2, y2);
  digitalWriteFast(B_RS, HIGH);

  _fast_fill_16(fch, fcl, ((long(x2 - x1) + 1) * (long(y2 - y1) + 1)));

  digitalWriteFast(B_CS, HIGH);

}

/**************************************************************************/
void ssd1963::fillRect(int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color)
{
  setColor(color);
  fillRect(x1, y1, x2, y2);
}

/**************************************************************************/
void  ssd1963::drawCircle(int16_t x0, int16_t y0, int16_t r)
{
  int16_t f = 1 - r;
  int16_t ddF_x = 1;
  int16_t ddF_y = -2 * r;
  int16_t x = 0;
  int16_t y = r;

  startWrite();
  drawPixel(x0, y0 + r);
  drawPixel(x0, y0 - r);
  drawPixel(x0 + r, y0);
  drawPixel(x0 - r, y0);

  while (x < y) {
    if (f >= 0) {
      y--;
      ddF_y += 2;
      f += ddF_y;
    }
    x++;
    ddF_x += 2;
    f += ddF_x;

    drawPixel(x0 + x, y0 + y);
    drawPixel(x0 - x, y0 + y);
    drawPixel(x0 + x, y0 - y);
    drawPixel(x0 - x, y0 - y);
    drawPixel(x0 + y, y0 + x);
    drawPixel(x0 - y, y0 + x);
    drawPixel(x0 + y, y0 - x);
    drawPixel(x0 - y, y0 - x);
  }
  endWrite();
}

void  ssd1963::drawRect(int x1, int y1, int x2, int y2)
{
  int16_t w = x2 - x1, h = y2 - y1;

  startWrite();
  writeFastHLine(x1, y1, w);
  writeFastHLine(x1, y1 + h - 1, w);
  writeFastVLine(x1, y1, h);
  writeFastVLine(x1 + w - 1, y1, h);

  //  drawLine(x1, y1, x2, y1);
  //  drawLine(x2, y1, x2, y2);
  //  drawLine(x2, y2, x1, y2);
  //  drawLine(x1, y2, x1, y1);
  endWrite();
}

void  ssd1963::startWrite()
{
  digitalWriteFast(B_CS, LOW);
  digitalWriteFast(B_RS, HIGH);
}

void  ssd1963::endWrite()
{
  digitalWriteFast(B_CS, HIGH);
}

void  ssd1963::drawPixel(int16_t x, int16_t y)
{
  digitalWriteFast(B_CS, LOW);
  setXY (x, y, x, y);
  tft_Write_DATA (fch, fcl);
  digitalWriteFast(B_CS, HIGH);
}
void ssd1963::drawPixel(int16_t x, int16_t y, uint16_t color)
{
  setColor(color);
  drawPixel(x, y);
}

void  ssd1963::drawLine(int x1, int y1, int x2, int y2)
{
  unsigned int  dx = (x2 > x1 ? x2 - x1 : x1 - x2);
  short         xstep =  x2 > x1 ? 1 : -1;
  unsigned int  dy = (y2 > y1 ? y2 - y1 : y1 - y2);
  short         ystep =  y2 > y1 ? 1 : -1;
  int           col = x1, row = y1;

  digitalWriteFast(B_CS, LOW);
  if (dx < dy)
  {
    int t = - (dy >> 1);
    while (true)
    {
      setXY (col, row, col, row);
      tft_Write_DATA (fch, fcl);
      if (row == y2)
        return;
      row += ystep;
      t += dx;
      if (t >= 0)
      {
        col += xstep;
        t   -= dy;
      }
    }
  }
  else
  {
    int t = - (dx >> 1);
    while (true)
    {
      setXY (col, row, col, row);
      tft_Write_DATA (fch, fcl);
      if (col == x2)
        return;
      col += xstep;
      t += dy;
      if (t >= 0)
      {
        row += ystep;
        t   -= dx;
      }
    }
  }
  digitalWriteFast(B_CS, HIGH);
}

/*************************************************************************************************/
/*!
   @brief    Draw a circle with filled color
    @param    x0   Center-point x coordinate
    @param    y0   Center-point y coordinate
    @param    r   Radius of circle
*/
/**************************************************************************/
void  ssd1963::fillCircle(int16_t x0, int16_t y0, int16_t r)
{
  // Serial.println(x0);
  startWrite();
  writeFastVLine(x0, y0 - r, 2 * r + 1);
  fillCircleHelper(x0, y0, r, 3, 0);
  endWrite();
}

/**************************************************************************/
/*!
    @brief  Quarter-circle drawer with fill, used for circles and roundrects
    @param  x0       Center-point x coordinate
    @param  y0       Center-point y coordinate
    @param  r        Radius of circle
    @param  corners  Mask bits indicating which quarters we're doing
    @param  delta    Offset from center-point, used for round-rects
*/
/**************************************************************************/
void  ssd1963::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t corners, int16_t delta)
{
  int16_t f = 1 - r;
  int16_t ddF_x = 1;
  int16_t ddF_y = -2 * r;
  int16_t x = 0;
  int16_t y = r;
  int16_t px = x;
  int16_t py = y;

  delta++; // Avoid some +1's in the loop

  while (x < y) {
    if (f >= 0) {
      y--;
      ddF_y += 2;
      f += ddF_y;
    }
    x++;
    ddF_x += 2;
    f += ddF_x;
    // These checks avoid double-drawing certain lines, important
    // for the SSD1306 library which has an INVERT drawing mode.
    if (x < (y + 1)) {
      if (corners & 1)
        writeFastVLine(x0 + x, y0 - y, 2 * y + delta);
      if (corners & 2)
        writeFastVLine(x0 - x, y0 - y, 2 * y + delta);
    }


    if (y != py) {
      if (corners & 1)
        writeFastVLine(x0 + py, y0 - px, 2 * px + delta);
      if (corners & 2)
        writeFastVLine(x0 - py, y0 - px, 2 * px + delta);
      py = y;
    }
    px = x;
  }
}

/**************************************************************************/
void  ssd1963::writeFastVLine(int16_t x, int16_t y, int16_t h)
{
  // Overwrite in subclasses if startWrite is defined!
  // Can be just writeLine(x, y, x, y+h-1);
  // or writeFillRect(x, y, 1, h);
  drawFastVLine(x, y, h);
}

/**************************************************************************/
/*!
   @brief    Write a perfectly horizontal line, overwrite in subclasses if
   startWrite is defined!
    @param    x   Left-most x coordinate
    @param    y   Left-most y coordinate
    @param    w   Width in pixels
*/
/**************************************************************************/
void  ssd1963::writeFastHLine(int16_t x, int16_t y, int16_t w)
{
  // Overwrite in subclasses if startWrite is defined!
  // Example: writeLine(x, y, x+w-1, y);
  // or writeFillRect(x, y, w, 1);
  drawFastHLine(x, y, w);
}

/**************************************************************************/
/*!
   @brief    Draw a perfectly vertical line (this is often optimized in a
   subclass!)
    @param    x   Top-most x coordinate
    @param    y   Top-most y coordinate
    @param    h   Height in pixels
*/
/**************************************************************************/
void  ssd1963::drawFastVLine(int16_t x, int16_t y, int16_t h)
{
  startWrite();
  writeLine(x, y, x, y + h - 1);
  endWrite();
}

/**************************************************************************/
/*!
   @brief    Draw a perfectly horizontal line (this is often optimized in a
   subclass!)
    @param    x   Left-most x coordinate
    @param    y   Left-most y coordinate
    @param    w   Width in pixels
*/
/**************************************************************************/
void  ssd1963::drawFastHLine(int16_t x, int16_t y, int16_t w)
{
  startWrite();
  writeLine(x, y, x + w - 1, y);
  endWrite();
}

/**************************************************************************/
/*!
   @brief    Write a pixel, overwrite in subclasses if startWrite is defined!
    @param   x   x coordinate
    @param   y   y coordinate   @param    color 16-bit 5-6-5 Color to fill with
*/
/**************************************************************************/
void  ssd1963::writePixel(int16_t x, int16_t y)
{
  drawPixel(x, y);
}

/**************************************************************************/
/*!
   @brief   Draw a triangle with no fill color
    @param    x0  Vertex #0 x coordinate
    @param    y0  Vertex #0 y coordinate
    @param    x1  Vertex #1 x coordinate
    @param    y1  Vertex #1 y coordinate
    @param    x2  Vertex #2 x coordinate
    @param    y2  Vertex #2 y coordinate
    @param    color 16-bit 5-6-5 Color to draw with
*/
/**************************************************************************/
void  ssd1963::drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2)
{
  drawLine(x0, y0, x1, y1);
  drawLine(x1, y1, x2, y2);
  drawLine(x2, y2, x0, y0);
}

/**************************************************************************/
/*!
   @brief     Draw a triangle with color-fill
    @param    x0  Vertex #0 x coordinate
    @param    y0  Vertex #0 y coordinate
    @param    x1  Vertex #1 x coordinate
    @param    y1  Vertex #1 y coordinate
    @param    x2  Vertex #2 x coordinate
    @param    y2  Vertex #2 y coordinate
    @param    color 16-bit 5-6-5 Color to fill/draw with
*/
/**************************************************************************/
void  ssd1963::fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2)
{

  int16_t a, b, y, last;

  // Sort coordinates by Y order (y2 >= y1 >= y0)

  if (y0 > y1)
  { //zz
    _swap_int16_t(y0, y1);
    _swap_int16_t(x0, x1);
  }

  if (y1 > y2)
  {
    _swap_int16_t(y1, y2);
    _swap_int16_t(x1, x2);

  }

  if (y0 > y1)
  {
    _swap_int16_t(y0, y1);
    _swap_int16_t(x0, x1);
  }

  startWrite();
  if (y0 == y2) { // Handle awkward all-on-same-line case as its own thing
    a = b = x0;
    if (x1 < a)
      a = x1;
    else if (x1 > b)
      b = x1;
    if (x2 < a)
      a = x2;
    else if (x2 > b)
      b = x2;
    writeFastHLine(a, y0, b - a + 1);
    endWrite();
    return;
  }

  int16_t dx01 = x1 - x0, dy01 = y1 - y0, dx02 = x2 - x0, dy02 = y2 - y0,
          dx12 = x2 - x1, dy12 = y2 - y1;
  int32_t sa = 0, sb = 0;

  // For upper part of triangle, find scanline crossings for segments
  // 0-1 and 0-2.  If y1=y2 (flat-bottomed triangle), the scanline y1
  // is included here (and second loop will be skipped, avoiding a /0
  // error there), otherwise scanline y1 is skipped here and handled
  // in the second loop...which also avoids a /0 error here if y0=y1
  // (flat-topped triangle).
  if (y1 == y2)
    last = y1; // Include y1 scanline
  else
    last = y1 - 1; // Skip it

  for (y = y0; y <= last; y++) {
    a = x0 + sa / dy01;
    b = x0 + sb / dy02;
    sa += dx01;
    sb += dx02;
    /* longhand:
      a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
      b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
    */
    if (a > b)
      _swap_int16_t(a, b);
    writeFastHLine(a, y, b - a + 1);
  }

  // For lower part of triangle, find scanline crossings for segments
  // 0-2 and 1-2.  This loop is skipped if y1=y2.
  sa = (int32_t)dx12 * (y - y1);
  sb = (int32_t)dx02 * (y - y0);
  for (; y <= y2; y++) {
    a = x1 + sa / dy12;
    b = x0 + sb / dy02;
    sa += dx12;
    sb += dx02;
    /* longhand:
      a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
      b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
    */
    if (a > b)
      _swap_int16_t(a, b);
    writeFastHLine(a, y, b - a + 1);
  }
  endWrite();
}

/**************************************************************************/
void  ssd1963::fillScreen(uint16_t color)
{
  setColor(color);
  fillRect(0, 0, DWIDTH - 1, DHEIGHT - 1);
}

/**************************************************************************/
/*!
   @brief    Write a line.  Bresenham's algorithm - thx wikpedia
    @param    x0  Start point x coordinate
    @param    y0  Start point y coordinate
    @param    x1  End point x coordinate
    @param    y1  End point y coordinate
    @param    color 16-bit 5-6-5 Color to draw with
*/
/**************************************************************************/
void  ssd1963::writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1)
{
#if defined(ESP8266)
  yield();
#endif
  int16_t steep = abs(y1 - y0) > abs(x1 - x0);
  if (steep) {
    _swap_int16_t(x0, y0);
    _swap_int16_t(x1, y1);
  }

  if (x0 > x1) {
    _swap_int16_t(x0, x1);
    _swap_int16_t(y0, y1);
  }

  int16_t dx, dy;
  dx = x1 - x0;
  dy = abs(y1 - y0);

  int16_t err = dx / 2;
  int16_t ystep;

  if (y0 < y1) {
    ystep = 1;
  } else {
    ystep = -1;
  }

  for (; x0 <= x1; x0++) {
    if (steep) {
      writePixel(y0, x0);
    } else {
      writePixel(x0, y0);
    }
    err -= dy;
    if (err < 0) {
      y0 += ystep;
      err += dx;
    }
  }
}

/**************************************************************************/
/*!
   @brief   Draw a rounded rectangle with no fill color
    @param    x   Top left corner x coordinate
    @param    y   Top left corner y coordinate
    @param    w   Width in pixels
    @param    h   Height in pixels
    @param    r   Radius of corner rounding
    @param    color 16-bit 5-6-5 Color to draw with
*/
void  ssd1963::drawRoundRect(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t r)
{
  int16_t w = x2 - x1;
  int16_t h = y2 - y1;
  int16_t max_radius = ((w < h) ? w : h) / 2; // 1/2 minor axis
  if (r > max_radius)
    r = max_radius;
  // smarter version
  startWrite();
  writeFastHLine(x1 + r, y1, w - 2 * r);         // Top
  writeFastHLine(x1 + r, y1 + h - 1, w - 2 * r); // Bottom
  writeFastVLine(x1, y1 + r, h - 2 * r);         // Left
  writeFastVLine(x1 + w - 1, y1 + r, h - 2 * r); // Right
  // draw four corners
  drawCircleHelper(x1 + r, y1 + r, r, 1);
  drawCircleHelper(x1 + w - r - 1, y1 + r, r, 2);
  drawCircleHelper(x1 + w - r - 1, y1 + h - r - 1, r, 4);
  drawCircleHelper(x1 + r, y1 + h - r - 1, r, 8);
  endWrite();
}

/**************************************************************************/
/*!
    @brief    Quarter-circle drawer, used to do circles and roundrects
    @param    x0   Center-point x coordinate
    @param    y0   Center-point y coordinate
    @param    r   Radius of circle
    @param    cornername  Mask bit #1 or bit #2 to indicate which quarters of
              the circle we're doing
    @param    color 16-bit 5-6-5 Color to draw with
*/
/**************************************************************************/
void  ssd1963::drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername)
{
  int16_t f = 1 - r;
  int16_t ddF_x = 1;
  int16_t ddF_y = -2 * r;
  int16_t x = 0;
  int16_t y = r;

  while (x < y) {
    if (f >= 0) {
      y--;
      ddF_y += 2;
      f += ddF_y;
    }
    x++;
    ddF_x += 2;
    f += ddF_x;
    if (cornername & 0x4) {
      writePixel(x0 + x, y0 + y);
      writePixel(x0 + y, y0 + x);
    }
    if (cornername & 0x2) {
      writePixel(x0 + x, y0 - y);
      writePixel(x0 + y, y0 - x);
    }
    if (cornername & 0x8) {
      writePixel(x0 - y, y0 + x);
      writePixel(x0 - x, y0 + y);
    }
    if (cornername & 0x1) {
      writePixel(x0 - y, y0 - x);
      writePixel(x0 - x, y0 - y);
    }
  }
}

/**************************************************************************/
/*!
   @brief   Draw a rounded rectangle with fill color
    @param    x   Top left corner x coordinate
    @param    y   Top left corner y coordinate
    @param    w   Width in pixels
    @param    h   Height in pixels
    @param    r   Radius of corner rounding
    @param    color 16-bit 5-6-5 Color to draw/fill with
*/
/**************************************************************************/
void  ssd1963::fillRoundRect(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t r)
{
  int16_t w = x2 - x1;
  int16_t h = y2 - y1;
  int16_t max_radius = ((w < h) ? w : h) / 2;       // 1/2 minor axis
  if (r > max_radius)
    r = max_radius;
  // smarter version
  startWrite();
  writeFillRect(x1 + r, y1, w - 2 * r, h);
  // draw four corners
  fillCircleHelper(x1 + w - r - 1, y1 + r, r, 1, h - 2 * r - 1);
  fillCircleHelper(x1 + r, y1 + r, r, 2, h - 2 * r - 1);
  endWrite();
}

/**************************************************************************/
/*!
   @brief    Write a rectangle completely with one color, overwrite in
   subclasses if startWrite is defined!
    @param    x   Top left corner x coordinate
    @param    y   Top left corner y coordinate
    @param    w   Width in pixels
    @param    h   Height in pixels
   @param    color 16-bit 5-6-5 Color to fill with
*/
/**************************************************************************/
void  ssd1963::writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h)
{
  // Overwrite in subclasses if desired!
  fillRect(x, y, x + w, y + h);
  // Serial.print(x); Serial.print(" "); Serial.print(y); Serial.print(" "); Serial.print(w); Serial.print(" "); Serial.print(h);
}

/************************************************************************************************/
void ssd1963::invertDisplay()
{
  digitalWriteFast(B_CS, LOW);    // chip select on
  tft_Write_COMMAND(0x21);        // invert display
  digitalWriteFast(B_CS, HIGH);   // chip select off
}

/************************************************************************************************/
void ssd1963::unInvertDisplay()
{
  digitalWriteFast(B_CS, LOW);    // chip select on
  tft_Write_COMMAND(0x20);        // unInvert display
  digitalWriteFast(B_CS, HIGH);   // chip select off
}

display.h

#ifndef __ssd1963_H__
#define __ssd1963_H__

#include "Arduino.h"
#include "gfxfont.h"
#include "Print.h"

// Color definitions
#define NAVY        0x000F          ///<   0,   0, 123
#define DARKGREEN   0x03E0          ///<   0, 125,   0
#define DARKCYAN    0x03EF          ///<   0, 125, 123
#define MAROON      0x7800          ///< 123,   0,   0
#define PURPLE      0x780F          ///< 123,   0, 123
#define OLIVE       0x7BE0          ///< 123, 125,   0
#define LIGHTGREY   0xC618          ///< 198, 195, 198
#define DARKGREY    0x7BEF          ///< 123, 125, 123
#define BLUE        0x001F          ///<   0,   0, 255
#define GREEN       0x07E0          ///<   0, 255,   0
#define CYAN        0x07FF          ///<   0, 255, 255
#define RED         0xF800          ///< 255,   0,   0
#define MAGENTA     0xF81F          ///< 255,   0, 255
#define YELLOW      0xFFE0          ///< 255, 255,   0
#define ORANGE      0xFD20          ///< 255, 165,   0
#define GREENYELLOW 0xAFE5          ///< 173, 255,  41
#define PINK 0xFC18                 ///< 255, 130, 198
#define BACKGROUND  0xA514
#define BUTTONCOLOR 0xAD75
#define BLACK       0x0000
#define BLUE        0x001F
#define DARKBLUE    0x0016
#define YELLOW      0xFFE0
#define RED         0xF800
#define DARKRED     0xA800
#define GREEN       0x07E0
#define WHITE       0xFFFF
#define LIGHTGRAY   0xb618
#define GRAY        0x7410
#define DARKGRAY    0x3208

// Teensy 4.0 pins
#define DB_0 29
#define DB_1 32
#define DB_2 33
#define DB_3 12
#define DB_4 11
#define DB_5 10
#define DB_6 9
#define DB_7 8
#define DB_8 7
#define DB_9 6
#define DB_10 5
#define DB_11 4
#define DB_12 3
#define DB_13 2
#define DB_14 1
#define DB_15 0


class  ssd1963 //: public Print
{
  public:

    ssd1963();
    ssd1963(int RS, int WR, int CS, int RST);
    void startWrite();
    void endWrite();
    void tft_Write_Bus(char ch, char cl);
    void tft_Write_DATA(char VL);
    void tft_Write_COMMAND(char VL);
    void writeFastVLine(int16_t x, int16_t y, int16_t h);
    void writeFastHLine(int16_t x, int16_t y, int16_t w);
    void drawFastHLine(int16_t x, int16_t y, int16_t w);
    void drawFastVLine(int16_t x, int16_t y, int16_t h);
    void writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1);
    void writePixel(int16_t x, int16_t y);
    void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h);
    void tft_Write_DATA(char VH, char VL);
    void startDisplay(void);
    void setColor(byte r, byte g, byte b);
    void setColor(uint16_t color);
    void setBackColor(byte r, byte g, byte b);
    void setBackColor(uint16_t bg);
    void invertDisplay();
    void unInvertDisplay();
    void print(int16_t x, int16_t y, String text, uint16_t fg, uint16_t bg);
    
    void setXY(word x1, word y1, word x2, word y2);
    void _fast_fill_16(int ch, int cl, long pix);
    void fillRect(int16_t x1, int16_t y1, int16_t x2, int16_t y2);
    void fillRect(int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);
    void drawRect(int x1, int y1, int x2, int y2);
    void drawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r);
    void fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r);
    void drawCircle(int16_t x0, int16_t y0, int16_t r);
    void drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername);
    void drawPixel(int16_t x, int16_t y);
    void drawPixel(int16_t x, int16_t y, uint16_t color);
    void writeRect(int16_t x, int16_t y, int16_t w, int16_t h, const uint16_t *pcolors);
    void inline tft_Write_Bus16(uint16_t data);
    void drawLine(int x1, int y1, int x2, int y2);
    void fillCircle(int16_t x0, int16_t y0, int16_t r);
    void fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t corners, int16_t delta);
    void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
    void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
    void fillScreen(uint16_t color);

    int16_t DWIDTH = 800;
    int16_t DHEIGHT = 480;
    uint8_t fch, fcl, bch, bcl;
    uint8_t B_RS, B_WR, B_CS, B_RST;

  private:

};

#endif

you need to implement the function write.
its marked virtual in your base class.

Added
virtual size_t write(uint8_t) = 0;
to the .h file

and added a dummy function

size_t ssd1963::write(uint8_t)
{
  return 0;
}

to the .cpp file:

A similar error occurs:

Arduino: 1.8.19 (Windows 10), TD: 1.57, Board: "Teensy 4.0, Serial, 600 MHz, Faster, US English"
Teensy40_800x400:27: error: cannot declare variable 'tft' to be of abstract type 'ssd1963'
ssd1963 tft(RS, WR, CS, RST);
^
In file included from C:\Users\Mike\Desktop\Teensy40_800x400\Teensy40_800x400.ino:1:0:
C:\Users\Mike\Desktop\Teensy40_800x400\display.h:59:8: note: because the following virtual functions are pure within 'ssd1963':
class ssd1963 : public Print
^
C:\Users\Mike\Desktop\Teensy40_800x400\display.h:65:20: note: virtual size_t ssd1963::write(uint8_t)
virtual size_t write(uint8_t) = 0;
^
Multiple libraries were found for "gfxfont.h"
Used: C:\Users\Mike\Documents\Arduino\libraries\Adafruit_GFX_Library
Not used: C:\Users\Mike\Documents\Arduino\libraries\arduino_652672
Not used: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\ssd1351
cannot declare variable 'tft' to be of abstract type 'ssd1963'

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Thank you!

That problem is gone. On to discover the next one;-)

"... isn't purely virtual anymore". It can still be declare virtual so that a child class might overload it.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.