简体   繁体   中英

C++ Overloading += for union of two bags with return type of void

I am trying to overload the += function (union) for my class called Bag. The return type is void so I cannot return a new array which was my original idea. Knowing this, I tried to simply copy the new array into a vector, which is shown in the code below. After filling bag1 and bag2, I used the overloaded function += which seems to work. I then displayed bag1 which I assume would contain the union of the two bags but it only contains the original.

Did I miss something important here as in not understanding the toVector() function?

I apologize for the long code, but I wasn't sure if I needed to omit parts of the unnecessary code related to this question.

I also tried to fill a third bag, bag3, to contain bag1 += bag2. But I assume I need to overload the = function to do that.

#include <iostream>
#include <string>

#include <vector>
using namespace std;

template<class T>
class Bag
{
public:
    Bag();
    int getCurrentSize() const;
    bool isEmpty() const;
    bool add(const T& new_entry);
    bool remove(const T& an_entry);
    /**
     @post item_count_ == 0
     **/
    void clear();
    /**
     @return true if an_etry is found in items_, false otherwise
     **/
    bool contains(const T& an_entry) const;

    /**
     @return the number of times an_entry is found in items_
     **/
    int getFrequencyOf(const T& an_entry) const;

    /**
     @return a vector having the same cotntents as items_
     **/
    std::vector<T> toVector() const;

    void display() const;  // displays the output 

    void operator+=(const Bag<T>& a_bag); //Union

protected:
    static const int DEFAULT_CAPACITY = 200;  //max size of items_
    T items_[DEFAULT_CAPACITY];              // Array of bag items
    int item_count_;                         // Current count of bag items
    int getIndexOf(const T& target) const;


};
template<class T>
Bag<T>::Bag(): item_count_(0)
{
}  // end default constructor

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

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


template<class T>
bool Bag<T>::add(const T& new_entry)
{
    bool has_room = (item_count_ < DEFAULT_CAPACITY);
    //bool notDup = items_.getFrequencyOf(new_entry) == 0; 
    if (has_room) //&& notDup) 
    {
        items_[item_count_] = new_entry;
        item_count_++;
        return true;
    }  // end if

    return false;
}  // end add

template<class T>
void Bag<T>::display() const {
    for(int x = 0; x < item_count_;x++)
        cout << items_[x] << ", "; 
}


/**
 @return true if an_etry was successfully removed from items_, false otherwise
 **/
template<class T>
bool Bag<T>::remove(const T& an_entry)
{
   int found_index = getIndexOf(an_entry);
    bool can_remove = !isEmpty() && (found_index > -1);
    if (can_remove)
    {
        item_count_--;
        items_[found_index] = items_[item_count_];
    }  // end if

    return can_remove;
}  // end remove


/**
 @post item_count_ == 0
 **/
template<class T>
void Bag<T>::clear()
{
    item_count_ = 0;
}  // end clear

template<class T>
int Bag<T>::getFrequencyOf(const T& an_entry) const
{
   int frequency = 0;
   int cun_index = 0;       // Current array index
   while (cun_index < item_count_)
   {
      if (items_[cun_index] == an_entry)
      {
         frequency++;
      }  // end if

      cun_index++;          // Increment to next entry
   }  // end while

   return frequency;
}  // end getFrequencyOf

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

template<class T>
std::vector<T> Bag<T>::toVector() const
{
   std::vector<T> bag_contents;
    for (int i = 0; i < item_count_; i++)
        bag_contents.push_back(items_[i]);

   return bag_contents;
}  // end toVector

// ********* PRIVATE METHODS **************//

template<class T>
void Bag<T>::operator+=(const Bag<T>& a_bag)
{
    Bag<T> uBag;
    for (int x = 0; x<item_count_; x++) {
        uBag.add(items_[x]);
    }

    for (int i = 0; i<a_bag.item_count_; i++) {
        uBag.add(a_bag.items_[i]);
    }
    //return uBag; // Since return type is void, I cannot do this 
    uBag.toVector(); 
}

main

Bag<int> bag1;
bag1.add(1);
bag1.add(2);

Bag<int> bag2;
bag2.add(3);
bag2.add(4); 

bag1.display(); //works 1,2
bag2.display(); //works 3,4

bag1+=bag2; //no errors when run without the code below 

bag1.display() // no errors, returns 1,2 which is not what I wanted 

Bag<int> bag3; 
bag3 = bag1 += bag2; //error: no match for ‘operator=’ (operand types are ‘Bag’ and ‘void’)
// I assume I need to overload the = function for this to work 

// main.cpp:9:7: note: candidate: Bag& Bag::operator=(const Bag&)
 class Bag
       ^~~~~~~~
main.cpp:9:7: note:   no known conversion for argument 1 from ‘void’ to ‘const Bag&’
main.cpp:9:7: note: candidate: Bag& Bag::operator=(Bag&&)
main.cpp:9:7: note:   no known conversion for argument 1 from ‘void’ to ‘Bag&&’

Since your question is about the operator += function, I will focus on that. The following should work:

template<class T>
Bag<T> & Bag<T>::operator += (const Bag<T>& a_bag)
{
    for (int i = 0; i < a_bag.item_count_; i++) {
        add(a_bag.items_[i]);
    }
    return *this;
}

By convention the operator += modifies the left hand side ( this ) by adding/appending the right hand side ( a_bag ). Hence no new object is created, but a reference to the left hand side, ie ( *this ) is returned which allows the =+ expression to be part of a larger expression, eg an argument in a function call.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM