c++ – Am I implementing S.O.L.I.D principles properly?

I am currently studying Object Oriented Design (OOD) and design patterns, and this hierarchy came into my mind, it simply makes a burger sandwich object, so I made it as follows (Read the comments in the code -there are some questions-):

//Bread Abstract Class
class Bread 
 {  
 public:
     string name; 
     int size; // because the bread have different sizes :D

     virtual Bread& getBread() = 0; // I made this a pure virtual function because 
                                    // I wanted the class to be abstract, was this a good idea?
                                    // because I think I broke the DRY concept by doing this.
     Bread(string name, int size)
         : name(name), size(size) {}
 };

 //Burger Abstract Class
 class Burger 
 {
 public:
     string type; 
     int size; //And the burgers of course :D

     virtual Burger& getBurger() = 0;  // As well as here!
     Burger(string type, int size)
         : type(type) ,size(size) {}
 };

//French Bread Concrete Class
 class frenchBread : public Bread 
 {
 public:
     Bread& getBread() override
     {
         return *this;
     }

     frenchBread(int size)
         :Bread("French Bread", size) {}
 };

 //White Bread Concrete Class
 class whiteBread : public Bread 
 {
 public:
     Bread& getBread() override
     {
         return *this;
     }

     whiteBread( int size)
         : Bread("White Bread", size) {}
 };

 //Vegeterian Base Class
 class vegieBurger : public Burger
 {
 public:
     Burger& getBurger () override
     {
         return *this;
     }

     vegieBurger (string name, int size)
     : Burger(name, size) {}

 };

 //Green Burger Derived Class From Vegeterian Burger Base Class
 class greenBurger : public vegieBurger 
 {
 public:
     greenBurger(int size)
         : vegieBurger("Green Burger", size) {}

 };

 //Non Vegeterian Burger Base Class
 class nonVegieBurger : public Burger 
 {
 public:
     Burger& getBurger()override
     {
         return *this;
     }

     nonVegieBurger(string name, int size)
         : Burger(name, size) {}

 };

 //Chicken Burger Derived Class From Non Vegeterian Base Class
 class chickenBurger: public nonVegieBurger 
 {
     chickenBurger(int size)
         : nonVegieBurger("Chicken Burger", size) {}

 };

 //Beef Burger Derived Class From Non Vegeterian Class
 class beefBurger : public nonVegieBurger 
 {
     beefBurger(int size)
         : nonVegieBurger("Beef Burger", size) {}

 };

 //Sandwich interface
 class I_Sandwich
 {
 public:
     virtual Bread& bread() = 0;
     virtual Burger& burger() = 0;
 };

 // Sandwich Class Contracts The Sandwich Interface 
 class sandwich : public I_Sandwich  {
 public: 
     Bread& bread1; 
     Burger& burger1; 

     sandwich(Bread& bread, Burger& burger)
         :bread1(bread), burger1(burger){}

     pair<Bread&, Burger&> getBreadAndBurger()
     {
         pair<Bread&, Burger&> result{bread1, burger1};
         return result;
     }

     Bread& bread () override
     {
         return bread1.getBread();
     }
     
     Burger& burger () override
     {
         return burger1.getBurger();
     }
 };

int main ()
{
    //And this is how I could make a green burger sandwich
    whiteBread bread(2);    // white bread of size 2 
    greenBurger burger(2);  // green burger of size 2
    sandwich greenBurgerWithWhiteBread(bread, burger);
}

I was trying to implement so concepts that I have learnt, like:

and I am planning to implement the builder pattern.

Noting that I am wholly new to this way of writing code because I didn’t put in mind abstractions and interfaces before.

The Question is:

  1. Is this approach good for implementing the concepts I stated above?
  2. Is there another pattern (or any other thing) that can be useful for implementing this particular hierarchy?