Home > database >  How to inherit from an abstract class properly in C ?
How to inherit from an abstract class properly in C ?

Time:02-16

I couldn't find a proper topic for this question as I haven't got a proper error message.

I'm trying to create a management system for a restaurant which mainly provides pizza as well as other foods(pasta, wings, etc). I want this system to be used by the staff. I have created an abstract class named Foods that can be used to inherit by other foods. So far I have created a class that inherits from Foods named Pizza. Below are my code.

PS: I have used namespaces for organize foods and staff members separately. As far as I know some people doesn't recommend namespace and my apologies if you're one of them.

interfaces.h

#include <vector>
#include <string>

namespace foods{
    class Food{
        double price;
        // since the sauces and drinks are given with foods.
        static const std::vector<std::string> sauces;
        static const std::vector<std::string> drinks;
    public:
        virtual int retPrice() = 0;
        virtual void ask() = 0; // ask user what to add
        virtual ~Food() = default;
    };
    const std::vector<std::string> Food::sauces = {"Blue cheese", "Garlic", "Honey BBQ", "Marinara"};
    const std::vector<std::string> Food::drinks = {"Pepsi", "Mountain Dew", "Coca Cola"};

    class Pizza: public Food{
        const double price;
        const std::string pizzaType; // whether it is chicken, beef, etc.
        const std::string size; // small, medium or large
    
        int crust = 1; // how crust it is from 1-5
        std::vector<std::string> toppings; // to store toppings
    public:
        Pizza(): price(15), pizzaType(" "), size(" "){}
        int retPrice() override; // the price should change according to the type
        void ask() override; // ask the customer for a pizza

        void createACustom(); // create a custom pizza with desired toppings
    };
};

functions.cpp

#include <iostream>
#include "interfaces.h"

namespace foods{
    int Pizza::retPrice(){
        return (price 5);
    }
    void Pizza::ask(){
        std::cout << "Hello World!";
    }
}

test.cpp

#include "interfaces.h"

int main(){
    foods::Pizza* pizza = new foods::Pizza();
}

And I'm getting following error.

/usr/bin/ld: /tmp/ccQRR5B8.o: warning: relocation against `_ZTVN5foods5PizzaE' in read-only section `.text._ZN5foods5PizzaC2Ev[_ZN5foods5PizzaC5Ev]'
/usr/bin/ld: /tmp/ccQRR5B8.o: in function `foods::Pizza::Pizza()':
test.cpp:(.text._ZN5foods5PizzaC2Ev[_ZN5foods5PizzaC5Ev] 0x2b): undefined reference to `vtable for foods::Pizza'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status

I tried using the keyword override and also made a default deconstructor, yet nothing seems working. I want to know what this error message means and a solution for this. In addition to that what is vtable?

Appreciate your time and answers.

EDIT 1

I have compiled it with g -Wall -Wextra test.cpp functions.cpp -o test, which is wrong and then I did g -Wall -Wextra test.cpp functions.cpp -o test and I'm getting following error.

/usr/bin/ld: /tmp/ccmv2G17.o:(.bss 0x0): multiple definition of `foods::Food::sauces[abi:cxx11]'; /tmp/ccuBNQjX.o:(.bss 0x0): first defined here
/usr/bin/ld: /tmp/ccmv2G17.o:(.bss 0x20): multiple definition of `foods::Food::drinks[abi:cxx11]'; /tmp/ccuBNQjX.o:(.bss 0x20): first defined here
collect2: error: ld returned 1 exit status

Why is it saying that it has multiple definitions?

CodePudding user response:

You need to implement the static member variables sauces and drinks in functions.cpp and not in interfaces.h.

functions.cpp

namespace foods {
  int Pizza::retPrice() {
    return (price   5);
  }
  void Pizza::ask() {
    std::cout << "Hello World!";
  }

  // implement the static variables here.
  const std::vector<std::string> Food::sauces = { "Blue cheese", "Garlic", "Honey BBQ", "Marinara" };
  const std::vector<std::string> Food::drinks = { "Pepsi", "Mountain Dew", "Coca Cola" };
}

And remove them from interfaces.h.

If you implement them in interfaces.h they end up being implemented in each .cpp file that includes interfaces.h.

It's basically the same problem as if you define a global variable in a .h file.

  • Related