使用派生类

时间:2017-05-05 16:31:40

标签: c++ operator-overloading operator-keyword

我在我的智慧结束时,在我需要一些帮助的情况下,在12个小时之后没有得到任何帮助。我相信我错过了这个问题的基本关键。我在下面有以下代码,对不起它很多,只是不想留下任何东西。让我说这确实是硬件,但是当你的老师没有发回电子邮件而谷歌没有任何帮助时,我恳求你们所有人的智慧和知识。

我的问题:我无法弄清楚如何为operatorBag.h类重载operator +。我相信我的原型很好,我只是无法弄清楚如何实现它。我已经尝试了很多东西,比如我写的东西,但请尽量少笑,因为我知道它错了,哈。谢谢你的帮助。

的main.cpp

** Listing 4-4. */
#include "BagInterface.h"
//#include "ArrayBag.h"
#include "LinkedBag.h"
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
/* no longer used in version 2.1, use << operator 
void displayBag(BagInterface<string>* bagPtr)
{
   cout << "The bag contains " << bagPtr->getCurrentSize()
   << " items:" << endl;
    vector<string> bagItems = bagPtr->toVector();

   int numberOfEntries = (int)bagItems.size();
   for (int i = 0; i < numberOfEntries; i++)
   {
      cout << bagItems[i] << " ";
   }  // end for
   cout << endl;
}  // end displayBag
******/
void bagTester(BagInterface<string>* bagPtr1, BagInterface<string>* bagPtr2)
{

   string items1[] = {"one", "six", "three", "four", "five", "one", "three"};
   string items2[] = {"one", "two", "three", "four", "five", "three"};
   for (int i = 0; i < 7; i++)
   {
      bagPtr1->add(items1[i]);
   }  // end for

   for (int i = 0; i < 6; i++)
   {
      bagPtr2->add(items2[i]);
   }  // end forA
   //displayBag(bagPtr1);
   cout << bagPtr1 << endl;
   cout << boolalpha << "contains 'one' for bag1 returns : " 
    << bagPtr1->contains("one")
           << " frequency: " << bagPtr1-> getFrequencyOf("one")
           <<endl<<endl;
   //displayBag(bagPtr2);
   cout << bagPtr2 << endl;
   cout << boolalpha << "contains 'one' for bag1 returns : " 
    << bagPtr2->contains("one")
           << " frequency: " << bagPtr2-> getFrequencyOf("one")
           <<endl<<endl;
}  // end bagTester
int main()
{
   BagInterface<string>* bagPtr1 = nullptr;
   BagInterface<string>* bagPtr2 = nullptr;
   BagInterface<string>* bagPtr3 = nullptr;
   char userChoice;
   cout << "Enter 'A' to test the array-based implementation\n"
   << " or 'L' to test the link-based implementation: ";
   cin >> userChoice;
   if (toupper(userChoice) == 'A')
   {
      //bagPtr1 = new ArrayBag<string>();
      //bagPtr2 = new ArrayBag<string>();
      //bagPtr3 = new ArrayBag<string>();
      //cout << "Testing the Array-Based Bag:" << endl;
   }
   else
   {
      bagPtr1 = new LinkedBag<string>();
      bagPtr2 = new LinkedBag<string>();
      bagPtr3 = new LinkedBag<string>();
      cout << "Testing the Link-Based Bag:" << endl;
   }  // end if
   // test both bags have items
   bagTester(bagPtr1, bagPtr2);
   //test Bag version 2.1 new methods
   //(*bagPtr3) = (*bagPtr1) + (*bagPtr2);
   //cout<<bagPtr3<<endl;
   //bagPtr3->bagSort();
   //cout<<bagPtr3;
   bagPtr1 = nullptr;
   bagPtr2 = nullptr;
   bagPtr3 = nullptr;
   cout << "All done!" << endl;

   return 0;
}  // end main*

BAGINTERFACE.H

/** Listing 1-1.
    @file BagInterface.h */
#ifndef _BAG_INTERFACE
#define _BAG_INTERFACE

#include <vector>
using namespace std;

template<class ItemType>
class BagInterface
{
public:
    //destructor
    virtual ~BagInterface() {}; 
   /** 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 f ills 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;

    /*******************************************************
    Description     :   Will combine contents of both bags including duplicates into a single bag
    Arguments       :   BagInterface<ItemType>* aBag
    Returns         :   BagInterface<ItemType>*
    Precondition    :   A valid BagInterface pointer object
    Postcondition   :   BagInteface pointer object with combined object elements
    *******************************************************/
   virtual BagInterface<ItemType>* combine( BagInterface<ItemType>* aBag) const = 0;

    /*******************************************************
    Description     :   Will show only items that are different in both bags
    Arguments       :   BagInterface<ItemType>* aBag
    Returns         :   BagInterface<ItemType>*
    Precondition    :   A valid BagInterface pointer object
    Postcondition   :   BagInteface pointer object that points to a bag with only elements
                    :   that are not shared by both bags.
    *******************************************************/
   virtual BagInterface<ItemType>* diff( BagInterface<ItemType>* aBag) const = 0;

    /*******************************************************
    Description     :   Elements that are shared by both bags are returned, no duplicates
    Arguments       :   BagInterface<ItemType>* aBag
    Returns         :   BagInterface<ItemType>*
    Precondition    :   A valid BagInterface pointer object
    Postcondition   :   BagInteface pointer object with elements that are shared with
                    :   both bags, no duplicates
    *******************************************************/
   virtual BagInterface<ItemType>* intersection( BagInterface<ItemType>* aBag) const = 0;

   virtual BagInterface<ItemType>& operator+(const BagInterface<ItemType>& aBag) const = 0;


}; // end BagInterface
#endif

NODE.H

/** @file Node.h 
    Listing 4-1 */
#ifndef _NODE
#define _NODE

template<class ItemType>
class Node
{
private:
   ItemType        item; // A data item
   Node<ItemType>* next; // Pointer to next node

public:
   Node();
   Node(const ItemType& anItem);
   Node(const ItemType& anItem, Node<ItemType>* nextNodePtr);
   void setItem(const ItemType& anItem);
   void setNext(Node<ItemType>* nextNodePtr);
   ItemType getItem() const ;
   Node<ItemType>* getNext() const ;
}; // end Node

#include "Node.cpp"
#endif

NODE.CPP

#pragma once
/** @file Node.cpp 
    Listing 4-2 */
#include "Node.h"
#include <cstddef>

template<class ItemType>
Node<ItemType>::Node() : next(nullptr)
{
} // end default constructor

template<class ItemType>
Node<ItemType>::Node(const ItemType& anItem) : item(anItem), next(nullptr)
{
} // end constructor

template<class ItemType>
Node<ItemType>::Node(const ItemType& anItem, Node<ItemType>* nextNodePtr) :
                item(anItem), next(nextNodePtr)
{
} // end constructor

template<class ItemType>
void Node<ItemType>::setItem(const ItemType& anItem)
{
   item = anItem;
} // end setItem

template<class ItemType>
void Node<ItemType>::setNext(Node<ItemType>* nextNodePtr)
{
   next = nextNodePtr;
} // end setNext

template<class ItemType>
ItemType Node<ItemType>::getItem() const
{
   return item;
} // end getItem

template<class ItemType>
Node<ItemType>* Node<ItemType>::getNext() const
{
   return next;
} // end getNext

LINKEDBAG.H

/** ADT bag: Link-based implementation.
    @file LinkedBag.h 
    Listing 4-3 */
#ifndef _LINKED_BAG
#define _LINKED_BAG

#include "BagInterface.h"
#include "Node.h"

template<class ItemType>
class LinkedBag : public BagInterface<ItemType>
{
private:
   Node<ItemType>* headPtr; // Pointer to first node
   int itemCount;           // Current count of bag items

   // Returns either a pointer to the node containing a given entry
   // or the null pointer if the entry is not in the bag.
   Node<ItemType>* getPointerTo(const ItemType& target) const;

public:
   LinkedBag();
   LinkedBag(const LinkedBag<ItemType>& aBag); // Copy constructor
   virtual ~LinkedBag();                       // Destructor should be virtual
   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;
   BagInterface<ItemType>* combine(BagInterface<ItemType>* aBag) const;
   BagInterface<ItemType>* diff(BagInterface<ItemType>* aBag) const;
   BagInterface<ItemType>* intersection(BagInterface<ItemType>* aBag) const;
   BagInterface<ItemType>& operator+(const BagInterface<ItemType>& aBag) const;

}; // end LinkedBag

#include "LinkedBag.cpp"
#endif

LINKEDBAG.CPP

#pragma once
/** ADT bag: Link-based implementation.
    @file LinkedBag.cpp */

#include "LinkedBag.h"
#include "Node.h"
#include <iostream>
using namespace std;
#include <cstddef>

template <class ItemType>
LinkedBag<ItemType>::LinkedBag()
    : headPtr(nullptr)
    , itemCount(0)
{
} // end default constructor

template <class ItemType> LinkedBag<ItemType>::LinkedBag(const LinkedBag<ItemType>& aBag)
{
    itemCount = aBag.itemCount;
    Node<ItemType>* origChainPtr = aBag.headPtr; // Points to nodes in original chain

    if(origChainPtr == nullptr)
    headPtr = nullptr; // Original bag is empty
    else {
    // Copy first node
    headPtr = new Node<ItemType>();
    headPtr->setItem(origChainPtr->getItem());

    // Copy remaining nodes
    Node<ItemType>* newChainPtr = headPtr;  // Points to last node in new chain
    origChainPtr = origChainPtr->getNext(); // Advance original-chain pointer

    while(origChainPtr != nullptr) {
        // Get next item from original chain
        ItemType nextItem = origChainPtr->getItem();

        // Create a new node containing the next item
        Node<ItemType>* newNodePtr = new Node<ItemType>(nextItem);

        // Link new node to end of new chain
        newChainPtr->setNext(newNodePtr);

        // Advance pointer to new last node
        newChainPtr = newChainPtr->getNext();

        // Advance original-chain pointer
        origChainPtr = origChainPtr->getNext();
    } // end while

    newChainPtr->setNext(nullptr); // Flag end of chain
    }                                  // end if
} // end copy constructor

template <class ItemType> LinkedBag<ItemType>::~LinkedBag()
{
    clear();
} // end destructor

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

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

template <class ItemType> bool LinkedBag<ItemType>::add(const ItemType& newEntry)
{
    // Add to beginning of chain: new node references rest of chain;
    // (headPtr is null if chain is empty)
    Node<ItemType>* nextNodePtr = new Node<ItemType>();
    nextNodePtr->setItem(newEntry);
    nextNodePtr->setNext(headPtr); // New node points to chain
    //   Node<ItemType>* nextNodePtr = new Node<ItemType>(newEntry, headPtr); // alternate code

    headPtr = nextNodePtr; // New node is now first node
    itemCount++;

    return true;
} // end add

template <class ItemType> vector<ItemType> LinkedBag<ItemType>::toVector() const
{
    vector<ItemType> bagContents;
    Node<ItemType>* curPtr = headPtr;
    int counter = 0;
    while((curPtr != nullptr) && (counter < itemCount)) {
    bagContents.push_back(curPtr->getItem());
    curPtr = curPtr->getNext();
    counter++;
    } // end while

    return bagContents;
} // end toVector

template <class ItemType> bool LinkedBag<ItemType>::remove(const ItemType& anEntry)
{
    Node<ItemType>* entryNodePtr = getPointerTo(anEntry);
    bool canRemoveItem = !isEmpty() && (entryNodePtr != nullptr);
    if(canRemoveItem) {
    // Copy data from first node to located node
    entryNodePtr->setItem(headPtr->getItem());

    // Delete first node
    Node<ItemType>* nodeToDeletePtr = headPtr;
    headPtr = headPtr->getNext();

    // Return node to the system
    nodeToDeletePtr->setNext(nullptr);
    delete nodeToDeletePtr;
    nodeToDeletePtr = nullptr;

    itemCount--;
    } // end if

    return canRemoveItem;
} // end remove

template <class ItemType> void LinkedBag<ItemType>::clear()
{
    Node<ItemType>* nodeToDeletePtr = headPtr;
    while(headPtr != nullptr) {
    headPtr = headPtr->getNext();

    // Return node to the system
    nodeToDeletePtr->setNext(nullptr);
    delete nodeToDeletePtr;

    nodeToDeletePtr = headPtr;
    } // end while
      // headPtr is nullptr; nodeToDeletePtr is nullptr

    itemCount = 0;
} // end clear

template <class ItemType> int LinkedBag<ItemType>::getFrequencyOf(const ItemType& anEntry) const
{
    int frequency = 0;
    int counter = 0;
    Node<ItemType>* curPtr = headPtr;
    while((curPtr != nullptr) && (counter < itemCount)) {
    if(anEntry == curPtr->getItem()) {
        frequency++;
    } // end if

    counter++;
    curPtr = curPtr->getNext();
    } // end while

    return frequency;
} // end getFrequencyOf

template <class ItemType> bool LinkedBag<ItemType>::contains(const ItemType& anEntry) const
{
    return (getPointerTo(anEntry) != nullptr);
} // end contains

/* ALTERNATE 1
template<class ItemType>
bool LinkedBag<ItemType>::contains(const ItemType& anEntry) const
{
   return getFrequencyOf(anEntry) > 0;
}
*/
/* ALTERNATE 2
template<class ItemType>
bool LinkedBag<ItemType>::contains(const ItemType& anEntry) const
{
   bool found = false;
   Node<ItemType>* curPtr = headPtr;
   int i = 0;
   while (!found && (curPtr != nullptr) && (i < itemCount))
   {
      if (anEntry == curPtr-<getItem())
      {
         found = true;
      }
      else
      {
         i++;
         curPtr = curPtr->getNext();
      }  // end if
   }  // end while

   return found;
}  // end contains
*/

// private
// Returns either a pointer to the node containing a given entry
// or the null pointer if the entry is not in the bag.
template <class ItemType> 
Node<ItemType>* LinkedBag<ItemType>::getPointerTo(const ItemType& anEntry) const
{
    bool found = false;
    Node<ItemType>* curPtr = headPtr;

    while(!found && (curPtr != nullptr)) {
    if(anEntry == curPtr->getItem())
        found = true;
    else
        curPtr = curPtr->getNext();
    } // end while

    return curPtr;
} // end getPointerTo

template <class ItemType> 
BagInterface<ItemType>* LinkedBag<ItemType>::combine(BagInterface<ItemType>* aBag) const
{
    vector<ItemType> items1 = aBag->toVector();
    vector<ItemType> items2 = this->toVector();

    BagInterface<ItemType>* newBag = new LinkedBag<ItemType>();

    if(!aBag->isEmpty()) {
    for(unsigned int i = 0; i < items1.size(); i++) {
        newBag->add(items1[i]);
    }
    }

    if(!this->isEmpty()) {
    for(unsigned int i = 0; i < items2.size(); i++) {
        newBag->add(items2[i]);
    }
    }

    return newBag;
}

template <class ItemType> BagInterface<ItemType>* LinkedBag<ItemType>::diff(BagInterface<ItemType>* aBag) const
{
    vector<ItemType> items1 = this->toVector();
    vector<ItemType> items2 = aBag->toVector();

    BagInterface<ItemType>* newBag = new LinkedBag<ItemType>();

    if(!aBag->isEmpty() && !this->isEmpty()) {
    for(unsigned int i = 0; i < items1.size(); i++) {
        for(unsigned int j = 0; j < items2.size(); j++) {
        if(items1[i] == items2[j]) {
            items1.erase(items1.begin() + i);
            items2.erase(items2.begin() + j);
            i = 0;
            j = -1;
        }
        }
    }
    }
    for(unsigned int i = 0; i < items1.size(); i++) {
    newBag->add(items1[i]);
    }
    return newBag;
}

template <class ItemType> BagInterface<ItemType>* LinkedBag<ItemType>::intersection(BagInterface<ItemType>* aBag) const
{
    vector<ItemType> items1 = this->toVector();
    vector<ItemType> items2 = aBag->toVector();

    BagInterface<ItemType>* newBag = new LinkedBag<ItemType>();

    if(!aBag->isEmpty() && !this->isEmpty()) {
    for(unsigned int i = 0; i < items1.size(); i++) {
        for(unsigned int j = 0; j < items2.size(); j++) {
        if(items1[i] == items2[j]) {
            newBag->add(items1[i]);
            items1.erase(items1.begin() + i);
            items2.erase(items2.begin() + j);
            i = 0;
            j = -1;
        }
        }
    }
    }
    return newBag;
}


template <class ItemType>
BagInterface<ItemType>& LinkedBag<ItemType>::operator+(const BagInterface<ItemType>& aBag) const
{
    //BagInterface<ItemType>* newBag = new LinkedBag();
    //return *newBag;

    BagInterface<ItemType> temp = new LinkedBag(aBag);

        Node<ItemType> *n = headPtr;
        while (n)
        {
            temp.Add(n->data);
            n = n->next;
        }

        n = aBag.headPtr;
        while (n)
        {
            temp.Add(n->data);
            n = n->next;
        }
        return temp;
}

1 个答案:

答案 0 :(得分:0)

目前尚不清楚代码中的问题是什么,因为不清楚运行它的预期输出是什么。您的代码是否会产生意外的输出?

从快速观察看起来您没有正确声明operator+。最有可能的是返回引用,而不是返回引用。也许您还应该有一种方法可以执行与opeartor+类似的操作,并让您的operator+简单地调用该方法:

template <class ItemType>
BagInterface<ItemType> LinkedBag<ItemType>::operator+(const BagInterface<ItemType>& aBag) const
{
    return doAdd(aBag); // method that does the same as `operator+`
}

在您的代码中,operator+返回BagInterface<ItemType>&而不是BagInterface<ItemType>