i've been playing around dynamic allocation , queue recently. keep in mind new data structures , i’ve been teaching myself watching youtube tutorials , reading tutorials websites forgive ignorance if don’t know every single thing there know subject. however, while playing around implementation of assignment operator queue, seem have made mistake somewhere in code. see whenever try , use assignment operator
i.e.
queue names2; names2 = names;
the assignment operator copies in queue except empty elements of array. implementing copy constructor or assignment operator wrong causing not add empty unused capacity newly created queue?
main.cpp
#include "queue.h"; int main() { queue names; names.enqueue("a"); names.enqueue("b"); names.enqueue("c"); names.dequeue(); names.enqueue("d"); names.showfullqueue(); queue names2; names2 = names; names2.showfullqueue(); names2.enqueue("tom"); names2.enqueue("alice"); names2.showfullqueue(); return 0; }
queue.h
#ifndef queue_h #define queue_h #include <iostream> #include <cstring> #include <algorithm> #include <string> using namespace std; class queue { public: queue(); //defualt costructor queue(const queue& source); //copy constructor ~queue(); //destructor queue& operator=(const queue& source); //assignament operator //not working void enqueue(string value); // add item queue string dequeue(); // remove item queue void showfullqueue() const; //memory allocation void memory(int currentcapacity); private: void shift(); string * arr; const static int front = 0; int back; int capacity; int usedcapacity; }; #endif // !queue_h
queue.cpp
#include "queue.h" queue::queue() { = -1; capacity = 1; usedcapacity = 0; arr = new string[capacity]; } queue::queue(const queue & source) { cout << "invoking copy constructor" << endl; this->back = source.back; this->capacity = source.capacity; this->usedcapacity = source.usedcapacity; arr = new string[source.capacity]; copy(source.arr, source.arr + usedcapacity, this->arr); } queue::~queue() { delete[] arr; } queue & queue::operator=(const queue & source) { if (this == &source) return *this; cout << "invoking assignament operator" << endl; queue temp(source); swap(temp.back, back); swap(temp.capacity, capacity); swap(temp.usedcapacity, capacity); swap(temp.arr, arr); return *this; } void queue::enqueue(string value) { ++back; arr[back] = value; usedcapacity++; memory(usedcapacity); } string queue::dequeue() { string returnvalue = arr[front]; shift(); usedcapacity--; memory(usedcapacity); return returnvalue; } void queue::showfullqueue() const { cout << "front: " << front << endl; cout << "back: " << << endl; (int = 0; < capacity; i++) { cout << arr[i] << ", "; } cout << endl; } void queue::memory(int currentcapacity) { if (currentcapacity >= capacity) { int newcapacity = (currentcapacity * 3) / 2 + 1; string * arr2 = new string[newcapacity]; copy(arr, arr + usedcapacity, arr2); delete[] arr; arr = arr2; capacity = newcapacity; } else cout << "allocation error"; } void queue::shift() { (int = front; <= back; i++) { arr[i] = arr[i + 1]; } --back; }
any appreciated. thank in advanced.
well, couple of bugs here fix..
your use of data member
back
, static memberfront
seem redundant me.i don't see beneficial use of
shift
function.
also, in copy assignment operator...
queue & queue::operator=(const queue & source) { if (this == &source) return *this; cout << "invoking assignament operator" << endl; queue temp(source); swap(temp.back, back); swap(temp.capacity, capacity); swap(temp.usedcapacity, capacity); //notice bug here...? swap(temp.arr, arr); return *this; }
well, here cleaned version... (notice few changes not using namespace std;
in global scope of header file; , moving unnecessary #includes
implementation file...
queue.h
#ifndef queue_h #define queue_h #include <string> //using namespace std; ...typically bad idea in header files class queue { public: queue(); //defualt costructor queue(const queue& source); //copy constructor ~queue(); //destructor queue& operator=(const queue& source); //assignment operator // working :-) void enqueue(std::string value); // add item queue string dequeue(); // remove item queue void showfullqueue() const; private: std::string* arr; int capacity; int usedcapacity; //memory allocation void memory(int currentcapacity); }; #endif // !queue_h
queue.cpp
#include "queue.h" //you can put remaining includes here #include <iostream> #include <algorithm> using namespace std; // can in cpp file... not bad idea.. :-) queue::queue() { capacity = 3; usedcapacity = 0; arr = new string[capacity](); } queue::queue(const queue & source) { cout << "invoking copy constructor" << endl; capacity = source.capacity; usedcapacity = source.usedcapacity; arr = new string[source.capacity](); copy(source.arr, source.arr + source.capacity, arr); } queue::~queue() { delete[] arr; } queue & queue::operator=(const queue & source) { if (this == &source) return *this; cout << "invoking assignament operator" << endl; using std::swap; //for adl: ...redundant here... since have using namespace std; queue temp(source); swap(temp.capacity, capacity); swap(temp.usedcapacity, usedcapacity); swap(temp.arr, arr); return *this; } void queue::enqueue(string value) { memory(usedcapacity); arr[usedcapacity] = value; ++usedcapacity; } string queue::dequeue() { string returnvalue = arr[--usedcapacity]; //memory(usedcapacity); //needless return returnvalue; } void queue::showfullqueue() const { //this styple prevents printing last comma on last item int = 0; (; < usedcapacity-1; i++) { cout << arr[i] << ", "; } cout << arr[i] << endl; } void queue::memory(int currentcapacity) { if (currentcapacity >= capacity) { int newcapacity = (currentcapacity * 3) / 2 + 1; string* arr2 = new string[newcapacity](); copy(arr, arr + capacity, arr2); delete[] arr; arr = arr2; capacity = newcapacity; } }
and there no changes main.cpp ...:-) see working here
of cause, there few more improvements can make like
- thinking exception safety
- using member initialization list
- rule of five