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.