How to use another class in my library

I'm trying to learn about making my own library and I'm stumped on using a class from another library in my library. I've been looking at libraries I have on my computer and searching Google, but I can't figure it out.

Here is a simple sketch that displays some text on a LCD screen. This works fine.

#include <Wire.h>
#include <Adafruit_GFX.h>      // http://github.com/adafruit/Adafruit-GFX-Library
#include <Adafruit_SSD1306.h>  // http://github.com/adafruit/Adafruit_SSD1306
#include "Menu.h"

#define OLED_RESET 9
Adafruit_SSD1306 display(OLED_RESET);

void setup() { 
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Hello");
  display.display();
}
void loop() {}

I'd like to move the display. lines into separate .h and .cpp files. These will be in the same directory as ino, not in the libraries folded. This is what I have for
MyTest.ino. I know I didn't create oledMenu object - I don't know how.

#include <Wire.h>
#include <Adafruit_GFX.h>  
#include <Adafruit_SSD1306.h> 

void setup() {  
  oledMenu.displayChoices(1);
}
void loop() {}

Here's Oled.h

#include <Arduino.h>
#include <Adafruit_SSD1306.h> 

class Menu
{
  public:
    Menu(Adafruit_SSD1306*, uint8_t resetPin);  // constructor
    void displayChoice(uint8_t choiceToShow); 
    
  private:
    uint8_t resetPin_;  // OLED reset pin
    Adafruit_SSD1306* oled; 
};

Here's Oled.cpp

#include "Oled.h"

Menu::Menu(Adafruit_SSD1306* Adafruit_SSD1306, uint8_t resetPin) // constructor
{
  resetPin_ = resetPin; // OLED reset pin
  oled = Adafruit_SSD1306;
 
  oled->begin(SSD1306_SWITCHCAPVCC, 0x3C);  
}

void Menu::displayChoice(uint8_t choiceToShow) {
  oled->clearDisplay();   
  oled->setCursor(0,0);
  if(choiceToShow == 1)
  { oled->println("Hello"); }
  else
  { oled->println("Goodbye"); }
  oled->display();  // refresh display
}

I don't know if I'm on the right track on not. I'm not sure how to create and use the Adafruit_SSD1306 in my cpp file. And I don't know how to create the Menu object (oledMenu.) to use in my ino. I tried a few different ways, but got compile errors.

Menu::Menu(Adafruit_SSD1306* Adafruit_SSD1306, uint8_t resetPin) // constructor

The argument name can NOT be the same as the argument type!

I'd like to move the display. lines into separate .h and .cpp files.

You need to pass the display object to your library (best/easiest) or create it in your class (may not be easy).

PaulS:

Menu::Menu(Adafruit_SSD1306* Adafruit_SSD1306, uint8_t resetPin) // constructor

The argument name can NOT be the same as the argument type!

I thought I read somewhere it was supposed to be, I guess I misunderstood. That's easy enough to change.

You need to pass the display object to your library (best/easiest) or create it in your class (may not be easy).

I'd like to go with "best/easy", but I'm not sure how to properly pass the display object to my library.

PaulS:

Menu::Menu(Adafruit_SSD1306* Adafruit_SSD1306, uint8_t resetPin) // constructor

The argument name can NOT be the same as the argument type!

This is where I read to do this, see #12:

Although they say this is for generic variables.

Here's what I came up with, it compiles but doesn't work. When I upload to my Leonardo it locks up and I actually lose my serial connection on the USB (I'm using a mac). The Seraial Port from the IDE menu drop down disappears. I'd actually prefer to not pass the display object in oledMenu.displayChoice(display, 1); I'd like to just have oledMenu.displayChoice(1);, but I couldn't figure that out.

.ino file

#include <Adafruit_SSD1306.h> 
#include <Wire.h>
#include <Adafruit_GFX.h>  
#include "Mytest.h"
#define RESETPIN 9

Adafruit_SSD1306 display(RESETPIN);
Menu oledMenu( display );

void setup(){
  Serial.begin(9600);
  delay(3000);
  oledMenu.displayChoice(display, 1);
}

void loop()
{}

.h file

#ifndef MYTEST_H
#define MYTEST_H

#include <Arduino.h>
#include <Adafruit_SSD1306.h> 
#include <Wire.h>
#include <Adafruit_GFX.h>  

class Menu 
{
    public:
    Menu(Adafruit_SSD1306& SSD1306);
    void displayChoice(Adafruit_SSD1306& SSD1306, uint8_t choiceToShow); 
};

#endif

.cpp file

#include "Mytest.h"
Menu::Menu(Adafruit_SSD1306& ssd1306)
{
    Serial.println("Menu::Menu");

    ssd1306.setCursor(0,0);
    ssd1306.setTextColor(WHITE);
    ssd1306.setTextSize(1);
    ssd1306.clearDisplay();
    ssd1306.println("constructor");
    ssd1306.display();
    delay(2000);
}

void Menu::displayChoice(Adafruit_SSD1306& ssd1306, uint8_t choiceToShow) 
{
  Serial.println("Menu::displayChoice");

  ssd1306.clearDisplay();   
  ssd1306.setCursor(0,0);
  if(choiceToShow == 1)
  { ssd1306.println("Hello"); }
  else
  { ssd1306.println("Goodbye"); }
  ssd1306.display();  // refresh display
}

ScottG:
This is where I read to do this, see #12:
C++ Programming Style Guidelines

Although they say this is for generic variables.

Notice how in those examples the variable name is not identical (Variable type has an upper case first letter, variable name has a lower case first letter). Personally I think that is a load of complete cobblers. What happens if you need to pass two variables of the same type, do you give them both the same name? no, of course not, you give the variable a sensible name which says what it does (e.g. strcpy(char* source, char* desitination))

ScottG:
.cpp file

#include "Mytest.h"

Menu::Menu(Adafruit_SSD1306& ssd1306)
{
    Serial.println("Menu::Menu");

ssd1306.setCursor(0,0);
    ssd1306.setTextColor(WHITE);
    ssd1306.setTextSize(1);
    ssd1306.clearDisplay();
    ssd1306.println("constructor");
    ssd1306.display();
    delay(2000);
}

void Menu::displayChoice(Adafruit_SSD1306& ssd1306, uint8_t choiceToShow)
{
  Serial.println("Menu::displayChoice");

ssd1306.clearDisplay();   
  ssd1306.setCursor(0,0);
  if(choiceToShow == 1)
  { ssd1306.println("Hello"); }
  else
  { ssd1306.println("Goodbye"); }
  ssd1306.display();  // refresh display
}

I think I know why my Leonardo freezes, I should not be putting all this code in the constructor (Menu::Menu). It should to in a separate function that's called form setup().

The problem is

  oled->begin(SSD1306_SWITCHCAPVCC, 0x3C);

inside the constructor.
This method cannot be executed in the constructor when the object is defined globally.

ScottG:
I think I know why my Leonardo freezes, I should not be putting all this code in the constructor (Menu::Menu). It should to in a separate function that's called form setup().

Absolutely it should not be in the constructor. That's why a lot of libraries use the "begin" function.