I am trying to write a program that will allow the user to add items into a shopping cart and remove them. The assignment is to use the Bag class that is already provided by the instructor. ShoppingCart class will derive from Bag class. I am struggling with the inheritance and compiling it.
I am confused with the `#include "Bag.cpp"` at the end of Bag.h file (which is included by the professor). When I add `#include "ShoppingCart.cpp"` and such, it gives me different errors. But in this case, I am getting the following error. If I add those includes, I get redefinition errors.
I am also confused with which files to include for the compiling process on PuTTy.
P.S. The assignment requires my files to be separate as header/implementation files.
1 2 3 4 5 6 7 8
g++ -o main main.cpp Item.cpp
Undefined first referenced
symbol in file
_ZN12ShoppingCartI4ItemEC1Ev /var/tmp//cc52nA1n.o
_ZN12ShoppingCartI4ItemE3addES0_ /var/tmp//cc52nA1n.o
_Zeq4ItemS_ /var/tmp//cc52nA1n.o
_ZN12ShoppingCartI4ItemE13getTotalPriceEv /var/tmp//cc52nA1n.o
ld: fatal: symbol referencing errors. No output written to main
#ifndef _BAG
#define _BAG
#include "BagInterface.h"
template<class ItemType>
class Bag : public BagInterface<ItemType>
{
private:
staticconstint DEFAULT_BAG_SIZE = 10;
ItemType items[DEFAULT_BAG_SIZE]; // array of bag items
int itemCount; // current count of bag items
int maxItems; // max capacity of the bag
// Returns either the index of the element in the array items that
// contains the given target or -1, if the array does not contain
// the target.
int getIndexOf(const ItemType& target) const;
public:
Bag();
int getCurrentSize() const;
bool isEmpty() const;
bool add(const ItemType& newEntry);
bool remove(const ItemType& anEntry);
void clear();
bool contains(const ItemType& anEntry) const;
int getFrequencyOf(const ItemType& anEntry) const;
vector<ItemType> toVector() const;
}; // end Bag
#include "Bag.cpp"
#endif
Template definitions must be visible from their point of instantiation. This is because function templates are not functions, and class templates are not classes, but are merely instructions for creating them.
Usually this means that template code is written in the header (rather: in the same file it's declared in, or entirely inline). If you want to separate implementation from the interface, then you may declare the templates in a header file and define the templates in another file, which is then included at the bottom of the header file. In my opinion, this workaround is usually a waste of time.
It is also possible to explicitly instantiate templates, which avoids the issue for a few selected types, but that feature isn't very often useful in practice. Look up "template instantiation" and "extern templates".
I am one who likes to put template class definition code in a separate file in many cases. While I understand @mbozzi's suggestion that it is usually a waste of time, I politely and mildly disagree. I like the separation of header information from instantiation instructions, and find that this organization mimics header/class separation for normal classes.
However, I do not use .cpp to represent the template instantiation code. I use another extension (usually .tcpp) to represent my template instantiation instruction file. The .tcpp file is included at the bottom of the header file. This makes sure that I do not try to compile my template code in a file by itself. A .cpp file should never be included by another .cpp file, and changing the extension of the template "source" file preserves this.
This method allows the user to see the header for the template class without getting bogged down in the details of the template class function code, but the compiler can still see the code when it is needed.
I have even had instances where I have a normal class with template member functions. In these cases I have a .h, a .cpp and a .tcpp file for the same class. This is rare, and it's really not as confusing as it sounds.
There are probably more people on this forum who put all of the template code into the header file than separate it into 2 files like I do. I get it. I'm not looking for a religious war here, and I'm not saying that my way is better. But if you like the header/source pattern and want to maintain it for template classes, this is how you can do it. Just don't name the source file .cpp.
Unfortunately, for the @OP, the Bag.cpp file was given as part of the assignment. This is an extremely disappointing name for that file. (If I were reviewing this code for work, I would insist that the file be renamed for these very reasons.) So, just realize that Bag.cpp is not really a .cpp file and do not pattern any of your code after line 32 in Bag.h.
Also if you #include the implementation file at the bottom of the header you shouldn't need to #include the header in the implementation file and you need to insure that the implementation file is not compiled as part of your project.