继承和未定义的引用:派生类

时间:2017-09-23 01:51:11

标签: c++ templates inheritance

我正在为一个班级的项目工作。该项目是关于继承。我的教授为我们提供了一个基类,并给了我们指令来覆盖我们被要求创建的派生类中的基类中的一些函数。我的所有对象和客户端都单独编译,但是当我尝试将它们放在一起时,我遇到了一个问题。标题,实现和客户端必须在此项目中分开。

g++ product.o basket.o client.o
client.o:client.cpp:(.text+0x37): undefined reference to`Cart<item>::Cart()'
client.o:client.cpp:(.text+0x147): undefined reference to `Cart<item>::add(item)'
client.o:client.cpp:(.text+0x27b): undefined reference to `Cart<item>::getTotalPrice()'
client.o:client.cpp:(.text+0x3d7): undefined reference to `Cart<item>::add(item)'
client.o:client.cpp:(.text+0x4df): undefined reference to `Cart<item>::remove(item)'
client.o:client.cpp:(.text+0x5fd): undefined reference to `Cart<item>::getTotalPrice()'
client.o:client.cpp:(.text$_ZNK3BagI4itemE10getIndexOfERKS0_[__ZNK3BagI4itemE10getIndexOfERKS0_]+0x4f): undefined reference to `operator==(item const&, item const&)'
client.o:client.cpp:(.text$_ZNK3BagI4itemE14getFrequencyOfERKS0_[__ZNK3BagI4itemE14getFrequencyOfERKS0_]+0x45): undefined reference to `operator==(item const&, item const&)'
collect2.exe: error: ld returned 1 exit status

以下是基类的代码:

#ifndef _BAG_INTERFACE
#define _BAG_INTERFACE

#include <vector>
using namespace std;

template<class ItemType>
class BagInterface
{
    public:
       /** Gets the current number of entries in this bag.
        @return The integer number of entries currently in the bag. */
       virtual int getCurrentSize() const = 0;

       /** Sees whether this bag is empty.
        @return True if the bag is empty, or false if not. */
       virtual bool isEmpty() const = 0;

       /** Adds a new entry to this bag.
        @post  If successful, newEntry is stored in the bag and
           the count of items in the bag has increased by 1.
        @param newEntry  The object to be added as a new entry.
        @return  True if addition was successful, or false if not. */
       virtual bool add(const ItemType& newEntry) = 0;

       /** Removes one occurrence of a given entry from this bag,
           if possible.
        @post  If successful, anEntry has been removed from the bag
           and the count of items in the bag has decreased by 1.
        @param anEntry  The entry to be removed.
        @return  True if removal was successful, or false if not. */
       virtual bool remove(const ItemType& anEntry) = 0;

       /** Removes all entries from this bag.
        @post  Bag contains no items, and the count of items is 0. */
       virtual void clear() = 0;

       /** Counts the number of times a given entry appears in bag.
        @param anEntry  The entry to be counted.
        @return  The number of times anEntry appears in the bag. */
       virtual int getFrequencyOf(const ItemType& anEntry) const = 0;

       /** Tests whether this bag contains a given entry.
        @param anEntry  The entry to locate.
        @return  True if bag contains anEntry, or false otherwise. */
       virtual bool contains(const ItemType& anEntry) const = 0;

       /** Empties and then fills a given vector with all entries that
           are in this bag.
        @return  A vector containing all the entries in the bag. */
       virtual vector<ItemType> toVector() const = 0;
    }; // end BagInterface
#endif


#include "Bag.h"
#include <cstddef>
template<class ItemType>
Bag<ItemType>::Bag() : itemCount(0), maxItems(DEFAULT_BAG_SIZE)
{
}  // end default constructor

template<class ItemType>
int Bag<ItemType>::getCurrentSize() const
{
    return itemCount;
}  // end getCurrentSize

template<class ItemType>
bool Bag<ItemType>::isEmpty() const
{
    return itemCount == 0;
}  // end isEmpty

template<class ItemType>
bool Bag<ItemType>::add(const ItemType& newEntry)
{
    bool hasRoomToAdd = (itemCount < maxItems);
    if (hasRoomToAdd)
    {
        items[itemCount] = newEntry;
        itemCount++;
    }  // end if

    return hasRoomToAdd;
}  // end add

template<class ItemType>
bool Bag<ItemType>::remove(const ItemType& anEntry)
{
   int locatedIndex = getIndexOf(anEntry);
    bool canRemoveItem = !isEmpty() && (locatedIndex > -1);
    if (canRemoveItem)
    {
        itemCount--;
        items[locatedIndex] = items[itemCount];
    }  // end if

    return canRemoveItem;
}  // end remove

template<class ItemType>
void Bag<ItemType>::clear()
{
    itemCount = 0;
}  // end clear

template<class ItemType>
int Bag<ItemType>::getFrequencyOf(const ItemType& anEntry) const
{
   int frequency = 0;
   int searchIndex = 0;
   while (searchIndex < itemCount)
   {
      if (items[searchIndex] == anEntry)
      {
         frequency++;
      }  // end if

      searchIndex++;
   }  // end while

   return frequency;
}  // end getFrequencyOf

template<class ItemType>
bool Bag<ItemType>::contains(const ItemType& anEntry) const
{
    return getIndexOf(anEntry) > -1;
}  // end contains

/* ALTERNATE 1
template<class ItemType>
bool Bag<ItemType>::contains(const ItemType& anEntry) const
{
    return getFrequencyOf(anEntry) > 0;
}  // end contains
*/
/* ALTERNATE 2 
template<class ItemType>
bool Bag<ItemType>::contains(const ItemType& anEntry) const
{
   bool found = false;
   for (int i = 0; !found && (i < itemCount); i++)
   {
      if (anEntry == items[i])
      {
         found = true;
      } // end if
   } // end for

   return found;
}  // end contains
*/

template<class ItemType>
vector<ItemType> Bag<ItemType>::toVector() const
{
    vector<ItemType> bagContents;
    for (int i = 0; i < itemCount; i++)
        bagContents.push_back(items[i]);
   return bagContents;
}  // end toVector

// private
template<class ItemType>
int Bag<ItemType>::getIndexOf(const ItemType& target) const
{
    bool found = false;
   int result = -1;
   int searchIndex = 0;
   // if the bag is empty, itemCount is zero, so loop is skipped
   while (!found && (searchIndex < itemCount))
   {
      if (items[searchIndex] == target)
      {
         found = true;
         result = searchIndex;
      } 
      else
      {
         searchIndex++;
      }  // end if
   }  // end while

   return result;
}  // end getIndexOf

以下是派生类

的代码
#ifndef BASKET_H
#define BASKET_H

#include "Bag.h"
#include "product.h"

#include <iostream>
#include <iomanip>

using namespace std;

template <class ItemType>
class Cart : public Bag<ItemType> {
private:
    double totalPrice;
public:
    Cart();
    double getTotalPrice();
    bool add(item);
    bool remove(item);

};

#endif

#include "basket.h"

using namespace std;

// Default Constructor
template <class ItemType>
Cart<ItemType>::Cart() {
    totalPrice = 0;
}

template <class ItemType>
bool Cart<ItemType>::add(item newItem) {

    bool added = Bag<ItemType>::add(newItem);

    totalPrice = totalPrice + (newItem.getitemQuantity() * newItem.getitemPrice());

    return added;
}

template <class ItemType>
bool Cart<ItemType>::remove(item anItem) {

    bool removed = Bag<ItemType>::remove(anItem);

    totalPrice = totalPrice - (anItem.getitemQuantity() * anItem.getitemPrice());

    return removed;
}

template <class ItemType>
double Cart<ItemType>::getTotalPrice() {
    return totalPrice;
}

这是我的主要计划:

#pragma once
#include <string>
#include "item2.h"
#include "Cart2.h"
#include "Bag.h"
#include "BagInterface.h"


using namespace std;

int main()
{


    item itemIn;
    Cart<item> shoppingCart;
    Bag<item> itemInBag;
    int itemCount = 0;
    vector<item> showItems;
    int modification = 1;

    char modify = 'y';
    char proceed = 'y';

    cout << "hello, thanks for shopping with us" << endl;
    cout << "please entr your items as the following: ItemName UnitPrice Quantity" << endl;
    cout << "other input formats will casue error!" << endl << "--> " <<endl;

    while (proceed == 'y')
    {
        cin >> itemIn;
        shoppingCart.add(itemIn);

        cout << "do you wish to add another item? " << endl << "--> ";
        cin >> proceed;

        if (proceed = 'n')
        {break;}

    }

    itemCount = itemInBag.getCurrentSize();
    showItems = itemInBag.toVector();
    for (int i = 0; i < itemCount; ++i)
    {
        cout << showItems[i];
    }

    cout << "would you like to modify your order? y/n" << endl << "--> " << endl;
    cin >> modify;

    while (modify = 'y')
    {
        cout << "do you want to (1) add an item or (2) remove an item? Press the coresponding number." << endl << "-->" << endl;
        cin >> modification;

        if (modification = 1)
        {

        }

    }
    cout << "done";
    return 0;


}

这是我们被要求做的另一个课程:

#ifndef PRODUCT_H
#define PRODUCT_H
#include <iostream>
#include <cstdlib>
#include <string>
#include <iomanip>
using namespace std;

class item
{
    private:
        string itemName;
        double itemPrice;
        int itemQuantity;
    public:
        item();
        void setitemName(string);
        void setitemPrice(double);
        void setitemQuantity(int);
        string getitemName() const;
        double getitemPrice() const;
        int getitemQuantity() const;
        friend ostream& operator<<(ostream& os, const item& right);
        friend istream& operator>>(istream& is, item& right);

};

bool operator ==(const item& i1, const item& i2);

#endif  

#include "product.h"
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <string>
using namespace std;

item::item()
{

}

void item::setitemName(string x)
{
    itemName = x;
}

void item::setitemPrice(double y)
{
    itemPrice = y;

}

void item::setitemQuantity(int z)
{
    itemQuantity = z;
}

string item::getitemName() const
{
    return itemName;
}

double item::getitemPrice() const
{
    return itemPrice;
}

int item::getitemQuantity() const
{
    return itemQuantity;
}

ostream& operator<<(ostream& os, const item& right)
{
    os <<right.itemName << right.itemPrice << right.itemQuantity << endl;
    return os;
}

istream& operator>>(istream& is, item& right)
{
    is >> right.itemName >> right.itemPrice >> right.itemQuantity;
    return is;
}   

bool operator ==(item& i1, item& i2) 
{
    return (i1.getitemName()==i2.getitemName() && i1.getitemPrice()==i2.getitemPrice()
            && i1.getitemQuantity()==i2.getitemQuantity());

}

如果我正在阅读编译器,问题可能在派生类中。我不确定发生了什么事情,并且感谢任何人都能给予的任何帮助。(注意:我的主程序还没有完成。)

0 个答案:

没有答案