I am trying to implement the function KidsQueue which should move families with more than 3 kids to the new counter and return it as a new queue, but the counters remain unchanged and counter 3 contains family with a number of kids above 3
#include <iostream>
#include <queue>
using namespace std;
class Family
{
private:
int id, noOfElders, noOfKids;
public:
bool operator ==(const Family &f)
{
if ((this->id!= f.id) || (this->noOfElders != f.noOfElders)||(this->noOfKids != f.noOfKids))
{
return false;
}
return true;
}
bool operator !=(const Family &f)
{
return !(*this==f); //////////////////////
}
Family(int ide=0, int eld=0, int kid=0) {
noOfElders = eld;
noOfKids = kid;
id = ide;
}
Family(const Family &a) {
noOfKids = a.noOfKids;
noOfElders = a.noOfElders;
id = a.id;
}
Family operator=(Family const &a) {
this->id = a.id;
this->noOfElders = a.noOfElders;
this->noOfKids = a.noOfKids;
return *this;
}
int getnoOfkids() const {
return noOfKids;
}
int getnoOfElders() const {
return noOfElders;
}
int getid() const {
return id;
}
void setnoOfKids(int x) {
noOfKids = x;
}
void setnoOfElders(int x) {
noOfElders = x;
}
void setid(int x) {
id = x;
}
friend ostream & operator<<(ostream & out, const Family & a)
{
out << "The id of the travelers are: " << a.id << endl;
out << "The number of elders are: " << a.noOfElders << endl;
out << "The number of kids are: " << a.noOfKids << endl;
return out;
}
friend istream &operator >> (istream &in, Family &a) {
in >> a.id;
in >> a.noOfElders;
in >> a.noOfKids;
return in;
}
};
queue<Family> KidsQueue(queue<Family> &a, queue<Family> &b) {
queue <Family> newA,newB;
queue <Family> result;
while(!a.empty())
{ if(a.front().getnoOfkids()>3) {
result.push(a.front()); a.pop();
}
else {
newA.push(a.front());
a.pop();
}
}
while(!b.empty())
{ if(b.front().getnoOfkids()>3) {
result.push(b.front()); b.pop();
}
else {
newB.push(b.front());
b.pop();
}
}
a=newA;
b=newB;
return result;
}
//print Queue
ostream &operator<<(ostream &out, const queue<Family> &q) {
queue<Family> tmp = q;
while (!tmp.empty()) {
cout << tmp.front() << endl;
tmp.pop();
}
return out;
}
int main() {
queue <Family> counter1;
queue <Family> counter2;
queue <Family> counter3;
counter1.push(Family(100, 2, 3));
counter1.push(Family(200, 2));
counter1.push(Family(400, 1));
counter1.push(Family(402, 1,4));
counter1.push(Family(789, 2));
counter2.push(Family(300, 2, 1));
counter2.push(Family(500, 1, 3));
counter2.push(Family(405, 3, 2));
counter2.push(Family(309, 1, 3));
counter2.push(Family(567, 2));
counter3 = KidsQueue(counter1, counter2);
cout << "Counter 3 has: " << endl << counter3;
cout << "Counter 1 after modification has: \n" << counter1;
cout << "Counter 2 after modification has: " << endl << counter2;
system("pause");
return 0;
}
In the main, I'm trying to write out all items that are added to the shopping cart. I posted my whole program for context of what is happening throughout. Currently, the program outputs the memory location of the pointer, but I'm terribly confused on how to de-reference it as nothing I've tried seems to work. Now, I think I'm going about this wrong, but I'm not sure how to simply implement printing out the items in the cart. Thank you so much for any help.
#include <iostream>
#include <string>
using namespace std;
class item{
private:
string title;
string description;
float price;
public:
item(string t, string d, float p){
this -> title = t;
this -> description = d;
this -> price = p;
}
//setters
void setTitle(string title){}
void setDescription(string description){}
void setPrice(float price){}
//getters
string getTitle(){
return title;
}
string getDescription(){
return description;
}
float getPrice(){
return price;
}
//virtual print function
virtual void print(){
cout << "Description: " << description << endl;
}
};//end class item____________________________________________________
class book : public item{
private:
int pageCount;
public :
//book();
book(string t, string d, float p, int pageCount) : item(t, d, p){
}
void setPageCount(int pageCount){}
int getPageCount(){
return pageCount;
}
void print(){
cout << "Type: Book \n";
//cout << "Description: " << description << endl;
}
};//end subclass book_________________________________________________________
class movie : public item{
private:
float length;
public:
movie(string t, string d, float p, float length) : item(t, d, p){
}
void setLength(float length){}
float getLength(){
return length;
}
void print(){
cout << "Type: Movie \n";
//cout << "Description: " << d << endl;
}
};//_______________________________________________________________________
class CD : public item{
private:
int trackCount;
public:
CD(string t, string d, float p, int trackCount) : item(t, d, p){
}
void setTrackCount(int trackCount){}
int getTrackCount(){
return trackCount;
}
void print(){
cout << "Type: CD \n";
//cout << "Description: " << description << endl;
}
};//___________________________________________________________________________
class ShoppingCart{
private:
int maxItems;
item** items;
public:
ShoppingCart(int maxItems){
this-> maxItems = maxItems;
this-> items = new item*[maxItems];
for (int i = 0; i < maxItems; i++){
//fills array with nothing, will store all items here
items[i] = nullptr;
}
}
void addItem(item* item){
for (int i = 1; i <= maxItems; i++){
if (this->items[i] == nullptr) {//check for empty spot in array
this->items[i] = item; //adds the item here
break; // exits if
}
}
}
void setMaxItems(int maxItems){}
int getMaxItems(){
return maxItems;
}
int getItemCount(){
int count = 0;
for (int i = 1; i <= maxItems; i++){
if (this->items[i] != nullptr){
count++;
}
}
return count;
}
void listItems(){
for (int i = 1; i < maxItems ; i ++){
if (this->items[i] != nullptr){
cout << "Item " << i <<
": "<< (items[i]) << endl;
}
}
}
item* getItemNum(int num){
return items[num];
}
};//____________________________________________________________
int main(){
book book_dawkins("The Selfish Gene", "Genetics", 8.75, 344);
Jacob.addItem(&book_dawkins);
Jacob.listItems(); //this outputs "Item 1: 0x61fd40"
return 0;
}
Dereferencing the pointer for printing is just a matter of doing cout << *items[i] . However, this will only work once you define the proper overload for printing an item.
First, implement a virtual function for item (and an override in book) that prints this onto an ostream&:
virtual ostream& print(ostream& os) const;
Next, use this in a overload for operator <<:
ostream& operator<<(ostream& os, const item& i) {
return i.print(os);
}
Taking a reference here is crucial, as it allows looking up the correct print method at run-time.
I have written a program which was given to me as a homework assignment (it's a bit longer). The issue is that it compiles in CodeBlocks but it does not compile in Visual Studio 2017 it says - binary '=': no operator found which takes a right-hand operand of type 'CAutomobile' (or there is no acceptable conversion.
I would like to ask why is that because I could not myself find the error? I tried commenting the operator =function but still the error remained.
#include <iostream>
#include <algorithm>
#include <string>
#include <stdlib.h>
using namespace std;
class CVehicle {
string name;
int year;
public:
CVehicle() {
name = "Car";
year = 1990;
}
CVehicle(string n, int y) {
name = n;
year = y;
}
CVehicle(const CVehicle& vc) {
name = vc.name;
year = vc.year;
}
void setName(string n) {
name = n;
}
void setYear(int y) {
year = y;
}
string getName() {
return name;
}
int& getYear() {
return year;
}
virtual void Print(ostream& os) = 0;
};
class CAutomobile :public CVehicle {
double litres;
public:
CAutomobile() :CVehicle() {
litres = 7.2;
}
CAutomobile(string nm, int yr, double l) :CVehicle(nm, yr) {
litres = l;
}
void setLitres(double l) {
l = litres;
}
double& getLitres() {
return litres;
}
void Print(ostream& os) override {
os << getName() << endl;
os << getYear() << endl;
os << litres << endl;
}
friend bool operator< (CAutomobile a1, CAutomobile a2) {
if (a1.litres < a2.litres) {
return true;
}
return false;
}
CAutomobile operator= (CAutomobile& at) {
CAutomobile au;
au.getName() = at.getName();
au.getYear() = at.getYear();
au.getLitres() = at.getLitres();
return au;
}
CAutomobile operator+(CAutomobile aut) {
CAutomobile a;
a.getLitres() = getLitres() + aut.getLitres();
return a;
}
friend ostream& operator<< (ostream& o, CAutomobile a) {
o << a.getName() << endl;
o << a.getYear() << endl;
o << a.getLitres() << endl;
return o;
}
};
int main()
{
CAutomobile a[] = {
CAutomobile(),
CAutomobile("Wolkswagen",1970,80.5),
CAutomobile("Fiat",1979,21.9),
CAutomobile("Opel",1978,13.7)
};
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
cout << "Name" << ' ' << a[i].getName() << endl;
cout << "Year" << ' ' << a[i].getYear() << endl;
cout << "Litres" << ' ' << a[i].getLitres() << endl;
}
int range = 2016 - 1990 + 1;
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
a[i].setLitres(rand() % 100 + 1);
a[i].setYear(rand() % range + 1996);
}
//сортираме масива по литри и извеждаме
//най малкия (първия) му елемент
for (int i = 0; i < sizeof(a-1); i++) {
for (int j = 0; j < sizeof(a-1); j++) {
if (a[j].getLitres() > a[j + 1].getLitres()) {
swap(a[j], a[j + 1]);
}
}
}
cout << a[0] << endl;
CAutomobile k = a[0] + a[3];
cout << k.getLitres() << endl;
}
CAutomobile::operator = is completely wrong. It takes a non-const reference and assignes its field to a new object. Instead it should take a const reference and modify current object.
CAutomobile & operator =(CAutomobile const & other)
{
assert(this != ::std::addressof(other)); // check for self-assignment
SetName(other.getName());
SetYear(other.getYear());
SetLitres(other.getLitres());
return *this;
}
This will bring up another problem: getters are not const-qualified, so they should be fixes as well:
string const & getName(void) const {
return name;
}
int const & getYear(void) const {
return year;
}
I was given an exercise on overloading operators by my tutor. He gave me the int main() function which cannot be changed. I was supposed to write the functions etc so that the code would work. Unfortunately I have a seg fault. I've noticed that if the
TSeries series4=series1(2,4);
cout << "Series4: " << series4 << endl;
lines are commented it's more or less working. I would be very grateful for your help.
#include <iostream>
class TSeries {
public:
TSeries()
{
_size = 0;
_capacity = 0;
_tab = NULL;
}
TSeries(float *tab, const int size)
{
_tab = new float[size];
for (int i = 0; i < size; i++) _tab[i] = tab[i];
_size = size;
_capacity = 0;
}
~TSeries() { delete[] _tab; }
TSeries & operator+=(float value) { return insert(value); }
TSeries & operator,(float value) { return insert(value); }
TSeries & operator+(const TSeries & s)
{
// if(this->_size != s._size) std::cout<<"Size doesn't match!"<<std::endl;
/*else
{
std::cout<<"whee";
for(int i; i<this->_size;i++)
{
//this->_tab[i] += s._tab[i];
std::cout<<"nothing";
}
return *this;
}*/
//std::cout<<"sth";
}
TSeries & operator()(int position1, int position2)
{
// return *this;
}
TSeries & insert(float k)
{
if (_size >= _capacity) Enlarge();
_tab[_size++] = k;
return *this;
}
friend std::ostream & operator<<(std::ostream & out, const TSeries & s);
private:
int _size, _capacity;
float *_tab, *_itr;
static int _nr;
void Enlarge()
{
_capacity = 2 * _capacity + 1;
float *tmp = new float[_capacity];
for (int i = 0; i < _size; ++i)
{
tmp[i] = _tab[i];
}
delete[] _tab;
_tab = tmp;
}
};
std::ostream & operator<<(std::ostream & out, const TSeries & s)
{
int przedostatni = s._size - 1;
out << "(";
for (int i = 0; i < s._size; i++)
{
out << (int)s._tab[i];
if (i != przedostatni)
out << ",";
}
out << ")" << std::endl;
}
using namespace std;
int main(int argc, char **argv) {
TSeries series1;
series1 += 1., 2., 4., 2.;
cout << "Series1: " << series1 << endl;
const int size = 7;
float tab[size] = { 3.,3.,3.,4.,5.,1.,0. };
const TSeries series2(tab, size);
cout << "Series2: " << series2 << endl << endl;
TSeries series3 = series1 + series2;
cout << "Series3: " << series3 << endl << endl;
series1 += 1., 0., 3.;
series3 = series1 + series2;
cout << " " << series1 << endl;
cout << " +" << series2 << endl;
cout << " ---------------------" << endl;
cout << "Series3: " << series3 << endl << endl;
TSeries series4 = series1(2, 4);
cout << "Series4: " << series4 << endl;
return 0;
}
/* output required:
Series1: (1,2,4,2)
Series2: (3,3,3,4,5,1,0)
Size doesn't match!
Series3: ()
(1,2,4,2,1,0,3)
+(3,3,3,4,5,1,0)
---------------------
Series3: (4,5,7,6,6,1,3)
Series4: (4,2)
*/
std::ostream & operator<<(std::ostream & out, const TSeries & s) doesn't return anything. Please add a return out at the end of the function
operator() and operator+ should both end with return *this
As Devolus already pointed out: You don't have a copy constructor and no operator=(const TSeries&) defined
You can use memcpy to copy the arrays faster.#
The i in the for-loop in operator+(const TSeries&) isn't initialized.
Your operator(int, int) does currently alter the original object. This doesn't seem right.
Code:
#include <iostream>
class TSeries {
public:
TSeries()
{
_size = 0;
_capacity = 0;
_tab = NULL;
}
TSeries(float *tab, const int size)
{
_size = size;
_capacity = 0;
_tab = new float[size];
memcpy(_tab, tab, _size*sizeof(float));
}
TSeries(const TSeries& other)
{
_size = other._size;
_capacity = other._capacity;
_tab = new float[_size];
memcpy(_tab, other._tab, _size*sizeof(float));
}
~TSeries()
{
delete[] _tab;
}
TSeries & operator+=(float value) { return insert(value); }
TSeries & operator,(float value) { return insert(value); }
TSeries & operator+(const TSeries & other)
{
if (this->_size != other._size)
{
std::cout << "Size doesn't match!" << std::endl;
}
else
{
//std::cout << "whee";
for (int i = 0; i < this->_size; i++)
{
_tab[i] += other._tab[i];
//std::cout << "nothing";
}
}
//std::cout<<"sth";
return *this;
}
TSeries& operator=(const TSeries& other)
{
_size = other._size;
_capacity = other._capacity;
//Create tmp in case of self-assignment
float *tmp = new float[_capacity];
memcpy(tmp, other._tab, _size*sizeof(float));
delete[] _tab;
_tab = tmp;
return *this;
}
TSeries operator()(int position1, int position2)
{
//TODO: Range-Check
return TSeries(_tab + position1, position2 - position1);
}
TSeries & insert(float k)
{
if (_size >= _capacity) Enlarge();
_tab[_size++] = k;
return *this;
}
friend std::ostream & operator<<(std::ostream & out, const TSeries & s);
private:
int _size, _capacity;
float *_tab, *_itr;
static int _nr;
void Enlarge()
{
_capacity = 2 * _capacity + 1;
float *tmp = new float[_capacity];
memcpy(tmp, _tab, _size*sizeof(float));
delete[] _tab;
_tab = tmp;
}
};
std::ostream & operator<<(std::ostream & out, const TSeries & s)
{
int przedostatni = s._size - 1;
out << "(";
for (int i = 0; i < s._size; i++)
{
out << (int)s._tab[i];
if (i != przedostatni)
out << ",";
}
out << ")" << std::endl;
return out;
}
using namespace std;
int main(int argc, char **argv) {
TSeries series1;
series1 += 1., 2., 4., 2.;
cout << "Series1: " << series1 << endl;
const int size = 7;
float tab[size] = { 3.,3.,3.,4.,5.,1.,0. };
const TSeries series2(tab, size);
cout << "Series2: " << series2 << endl << endl;
TSeries series3 = series1 + series2;
cout << "Series3: " << series3 << endl << endl;
series1 += 1., 0., 3.;
series3 = series1 + series2;
cout << " " << series1 << endl;
cout << " +" << series2 << endl;
cout << " ---------------------" << endl;
cout << "Series3: " << series3 << endl << endl;
TSeries series4 = series1(2, 4);
cout << "Series4: " << series4 << endl;
return 0;
}
/* output required:
Series1: (1,2,4,2)
Series2: (3,3,3,4,5,1,0)
Size doesn't match!
Series3: ()
(1,2,4,2,1,0,3)
+(3,3,3,4,5,1,0)
---------------------
Series3: (4,5,7,6,6,1,3)
Series4: (4,2)
*/
Output
Series1: (1,2,4,2)
Series2: (3,3,3,4,5,1,0)
Size doesn't match!
Series3: (1,2,4,2)
(4,5,7,6,6,1,3)
+(3,3,3,4,5,1,0)
---------------------
Series3: (4,5,7,6,6,1,3)
Series4: (7,6)
UPDATE:
Your operator+(const TSeries &) should look somewhat like this:
TSeries operator+(const TSeries & other)
{
if (this->_size != other._size)
{
std::cout << "Size doesn't match!" << std::endl;
return TSeries(); //Return empty object
}
TSeries tmp(*this); //Create copy
for (int i = 0; i < tmp._size; i++)
{
tmp._tab[i] += other._tab[i];
}
return tmp;
}
And your operator()(int, int) like this:
TSeries operator()(int position1, int position2)
{
if (position1 < 0) position1 = 0;
else if (position1 >= _size) position1 = _size - 1;
if (position2 < position1) position2 = position1;
else if (position2 >= _size) position2 = _size - 1;
return TSeries(_tab + position1, position2 - position1);
}
Maybe you want to throw exceptions in the error cases?
I'm probably missing something obvious here. This is my code (I'm just learning true C++, and I want to get some practice):
#include <iostream>
#include <cstring>
using namespace std;
class String {
private:
char * value;
int len;
friend ostream & operator<<(ostream & os, String s);
public:
String();
String(const char * base);
~String();
String operator+(String s);
String operator*(int n);
int length();
};
String::String() {
this->value = new char[0];
this->len = 0;
}
String::String(const char * base) {
this->value = new char[this->len = strlen(base)];
strcpy(this->value, base);
}
String::~String() {
delete [] this->value;
}
int String::length() {
return this->len;
}
String String::operator+(String s) {
String n;
delete [] n.value;
cout << "Upon entering, I am: \"" << *this << "\"\n";
n.value = new char[this->len + s.len];
for(int i = 0; i < this->len; i++) {
n.value[i] = this->value[i];
}
for(int i = 0; i < s.len; i++) {
n.value[i + this->len] = s.value[i];
}
n.len = this->len + s.len;
cout << "String::operator+(" << *this << ", " << s << ") succeeded with new value = \"" << n << "\"\n";
return n;
}
String String::operator*(int n) {
String s;
delete [] s.value;
s.value = new char[this->len * n];
for(int i = 0; i < this->len * n; i++) {
s.value[i] = this->value[i % this->len];
}
cout << "String::operator* succeeded with new value = \"" << s << "\"\n";
return s;
}
ostream & operator<<(ostream & os, String s) {
return os << s.value;
}
int main() {
String s("Hello, world!");
cout << s << "\nLength = " << s.length() << "\n\n";
cout << (s + String("\n")) * 5;
return 0;
}
And the string initializes and displays correctly, but my output is really strange; it seems that upon entering the operator+, "Hello, world!" suddenly becomes "x%r"?
C:\Users\Ryan\Documents\My Dropbox\C++ Projects>strings
Hello, world!
Length = 13
Upon entering, I am: "x%r"
String::operator+(x%r,
) succeeded with new value = "x%r"
String::operator* succeeded with new value = "╚%r"
─
Try this:
ostream & operator<<(ostream & os, const String& s) {
return os << s.value;
}
otherwise your should define copy constructor for your String class.
You need to provide copy constructor and assignment operator.
There are a lot of problems with your code.
You are managing your own memory. You should avoid doing this if at all possible.
You are consitantly forgetting that strings have a null terminator. In order to accomodate the strin Hello, world! you need a char buffer that is 14 bytes, not 13.
You have a len member variable that does effectively the same thing as the strlen function, except for the inconsistent consideration of #1 above.
Your string class does not have a copy constructor, which results in wild pointers and eventually crashes.
Here is a refactoring of your code that pretty much works.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;
class String {
private:
char * value;
// size_t len;
friend ostream & operator<<(ostream & os, String s);
public:
String();
String(const char * base);
String(const String& rhs)
{
value = new char[strlen(rhs.value)+1];
strcpy(value,rhs.value);
}
~String();
String operator+(String s);
String operator*(int n);
size_t length();
};
String::String() {
this->value = new char[0];
}
String::String(const char * base) {
this->value = new char[strlen(base)+1];
strcpy(this->value, base);
}
String::~String() {
delete [] this->value;
}
size_t String::length() {
return strlen(value);
}
String String::operator+(String s) {
String n;
delete [] n.value;
cout << "Upon entering, I am: \"" << *this << "\"\n";
n.value = new char[strlen(value)+strlen(s.value)+1];
for(int i = 0; i < strlen(value); i++) {
n.value[i] = this->value[i];
}
for(int i = 0; i < strlen(s.value); i++) {
n.value[i + strlen(value)] = s.value[i];
}
n.value[strlen(value)+strlen(s.value)] = '\0';
cout << "String::operator+(" << *this << ", " << s << ") succeeded with new value = \"" << n << "\"\n";
return n;
}
String String::operator*(int n) {
String s;
delete [] s.value;
s.value = new char[(strlen(value)*n)+1];
for(int i = 0; i < strlen(value) * n; i++) {
s.value[i] = this->value[i % strlen(value)];
}
s.value[strlen(value)*n] = '\0';
cout << "String::operator* succeeded with new value = \"" << s << "\"\n";
return s;
}
ostream & operator<<(ostream & os, String s) {
return os << s.value;
}
int main() {
String s("Hello, world!");
cout << s << "\nLength = " << s.length() << "\n\n";
cout << (s + String("\n")) * 5;
return 0;
}