我在我的智慧结束时,在我需要一些帮助的情况下,在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;
}
答案 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>
。