write out array created as pointer in subclass (C++) - c++

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.

Related

I can't somehow sort my linked queue nodes with a bubble sort algorithm

So, I was asked by my instructor to make a node containing a few variables and sort it by taking the hourlySalary variable as reference for each code. However, there seems to be a problem with the outputs. It isn't sorting the nodes at all. I tried to fix it for a while and gave up. Looked up some sources on the internet but still no luck. I am guessing that the problem is somewhere in the swapping function or the bubble sort function.
Here is my code.
#include <iostream>
using namespace std;
class myNumberIsEleven{
private:
struct linkedlist{
string firstName;
string lastName;
unsigned int age;
char gender;
int hourlySalary;
linkedlist *linker;
}*Ptr,*curPtr;
public:
int counter=0;
myNumberIsEleven(){
Ptr=NULL;
}
void printList(){
curPtr=Ptr;
while(curPtr!=NULL){
cout << curPtr->firstName << " " << curPtr->lastName << endl << curPtr->age << endl << curPtr->gender << endl << curPtr->hourlySalary << endl << "=====" << endl;
curPtr=curPtr->linker;
}
}
void add(int salary,string name,string lastname,int ageisjustanumber,char Gender){
linkedlist *newPtr = new linkedlist;
newPtr->hourlySalary = salary;
newPtr->firstName = name;
newPtr->lastName = lastname;
newPtr->gender = Gender;
newPtr->age = ageisjustanumber;
newPtr->hourlySalary = salary;
newPtr->linker = Ptr;
Ptr = newPtr;
counter++;
}
void Swap(linkedlist* a,linkedlist* b){
string temp_firstName;
string temp_LastName;
unsigned int temp_Age;
char temp_Gender;
int temp_hourlySalray;
temp_firstName = a->firstName;
temp_LastName = a->lastName;
temp_Age = a->age;
temp_Gender = a->gender;
temp_hourlySalray = a->hourlySalary;
a->firstName = b->firstName;
a->lastName = b->lastName;
a->age = b->age;
a->gender = b->gender;
a->hourlySalary = b->hourlySalary;
b->firstName = temp_firstName;
b->lastName = temp_LastName;
b->age = temp_Age;
b->gender = temp_Gender;
b->hourlySalary = temp_hourlySalray;
}
void bubbleSort(){
for(linkedlist* i=Ptr;i->linker != NULL;i=i->linker){
for(linkedlist* j = i->linker;j!=NULL;j=j->linker){
if(i->hourlySalary > i->hourlySalary){
Swap(i,j);
}
}
}
printList();
}
/*
void bubbleSort(int arr[], int n)
{
int i, j;
for (i = 0; i < n-1; i++)
// Last i elements are already in place
for (j = 0; j < n-i-1; j++)
if (arr[j] > arr[j+1])
swap(&arr[j], &arr[j+1]);
}
*/
};
int main()
{
myNumberIsEleven myNameIsBerkan;
myNameIsBerkan.add(1000,"berkan","iwontgivemysurname",21,'M');
myNameIsBerkan.add(2100,"ah","be",31,'F');
myNameIsBerkan.add(50,"uhmmm","something",10,'M');
myNameIsBerkan.add(69000,"elon","musk",44,'M');
myNameIsBerkan.bubbleSort();
return 0;
}

Exception thrown: write access violation

I am trying to implement a list structure, but when I wrote the insert() function which inserts an element in a specific position in the list, I get an error Exception thrown: write access violation.
pl was 0x34812B3A.
I tried alot to fix it but I really can't. I used try..throw..catch and still didn't get it, so what should I do.
This is my code:
List.h
#pragma once
#define MAXLIST 100
typedef struct List {
int size;
int entry[MAXLIST];
}list;
void createl(list*);
int ListEmpty(list*);
int ListFull(list*);
int sizel(list*);
void destroyl(list*);
void insert(int, int, list*);
void deletei(int* , int, list*);
void traversel(list*, void (*)(int));
void retrieve(int*, int, list*);
void replace(int, int, list*);
//int access(int , list*);
and this is the implementation (List.cpp)
#include <iostream>
#include "List.h"
using namespace std;
void createl(list* pl) {
pl->size = 0;
}
int isEmpty(list* pl) {
return !(pl->size);
}
int isFull(list* pl) {
return (pl->size == MAXLIST);
}
int sizel(list* pl) {
return pl->size;
}
void destroyl(list* pl) {
pl->size = 0;
}
void insert(int e, int p, list* pl) { //insert element e in the postion p in the list
for (int i = pl->size -1; i >= p; i--) {
pl->entry[i+1] = pl->entry[i];
}
pl->entry[p] = e;
pl->size++;
}
void deletei(int* pe, int p, list* pl) {
*pe = pl->entry[p];
for (int i = p + 1; i < pl->size; ++i) {
pl->entry[i-1] = pl->entry[i];
}
pl->size--;
}
void traversel(list* pl, void (*pf)(int e)) {
for (int i = 0; i < pl->size; ++i) {
(*pf)(pl->entry[i]);
}
}
void retrieve(int* pe, int p, list* pl) {
*pe = pl->entry[p];
}
void replace(int e, int p, list* pl) {
pl->entry[p] = e;
}
/*int access(int p, list* pl) {
return pl->entry[p];
}*/
I get the error here in function insert()
pl->entry[p] = e;
and this is a program to just check if my code works.
#include <iostream>
#include "List.h"
using namespace std;
void display(int e) {
cout << e << "\n";
}
int main() {
list l;
list* ptl = &l;
int t;
cout << "Put 5 elements:\n";
for (int i = 0; i < 5; ++i) {
cin >> t;
insert(t, sizel(ptl), ptl);
}
cout << "The list looks like a stack\n\n";
traversel(ptl, display);
cout << "The size of the list is: " << sizel(ptl) << endl;
insert(9, 2, ptl);
cout << "The size of the list is: " << sizel(ptl) << endl;
int temp;
deletei(&temp, 2, ptl);
cout << temp <<endl ;
traversel(ptl, display);
cout << "The size of the list is: " << sizel(&l) << endl;
int t2;
retrieve(&t2, 2, ptl);
cout << t2 << endl;
replace(4, 1, ptl);
traversel(ptl, display);
destroyl(ptl);
cout << "The size of the list is: " << sizel(ptl) << endl;
return 0;
}
Thank you for your time and helping me.
You used ptl, which points at l, without initializing l.
Add initialization like this:
int main() {
list l;
list* ptl = &l;
int t;
createl(ptl); // add initialization
cout << "Put 5 elements:\n";
for (int i = 0; i < 5; ++i) {
cin >> t;
insert(t, sizel(ptl), ptl);
}

Compilation error in C++ when using an assignment operator =?

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;
}

c++ unable to change members of array

i am really stuck on following problem:
2 classes:
class Article
{
char* _code;
char* _name;
double _price;
int _quantity;
public:
Article(char* code = "code", char * name = "name", double price = 0){
setCode(code);
setName(name);
_price = price;
_quantity = 0;
}
Article(Article & a){
setCode(a._code);
setName(a._name);
_price = a._price;
_quantity = a._quantity;
}
~Article(){
delete[] _code; _code = nullptr;
delete[] _name; _name = nullptr;
}
/*******SETTERS********/
void setCode(char* code){
int vel = strlen(code);
_code = new char[vel + 1];
strncpy_s(_code, vel + 1, code, _TRUNCATE);
}
void setName(char* name){
int vel = strlen(name);
_name = new char[vel + 1];
strncpy_s(_name, vel + 1, name, _TRUNCATE);
}
void setPrice(double c){ _price = c; }
/*******GETTERS********/
int getquantity(){ return _quantity; }
double getprice(){ return _price; }
//operator =
Article operator = (Article& a){
setName(a._name);
setCode(a._code);
_price = a._price;
_quantity = a._quantity;
return *this;
}
//operator-= decrease qnty for passed value.
bool operator-=(int v){
if (_quantity > v)
{
_quantity = _quantity - v;
return true;
}
cout << "Operacija nije moguca, stanje je manje nego vrijednsot za koju se umanjuje";
return false;
}
// operator ++ increase Qnty for 1.
Article operator++(int){
//Article A(_code, _name, _price);
this->_quantity++;
return *this;
}
//Preklopiti operator -- decrease value for 1.
Article operator--(){
if (_quantity >= 1)
{
_quantity--;
}
return *this;
}
//compare articles based on code.
bool operator==(Article & a){
if (strncmp(_code, a._code, strlen(_code)) == 0)
{
return true;
}
return false;
}
//operator <<
friend ostream & operator<<(ostream & COUT, Article & a);
};
ostream & operator<<(ostream & COUT, Article & a){
COUT << "code: " << a._code << endl << "name: " << a._name << endl << "price: " << a._price << ", Qnty: " << a._quantity << "\n ----------------------- \n\n";
return COUT;
}
class Item
{
Article _Article;
int* _quantity;
public:
Item(Article & a, int quantity) :_Article(a){
_quantity = new int(quantity);
}
Item() :_Article("StavkaR", "nameR", 0){
_quantity = new int(0);
}
Item(Item& s) :_Article(s._Article){
_quantity = new int(*s._quantity);
}
~Item(){
delete _quantity; _quantity = nullptr;
}
int getquantity(){ return *_quantity; }
void setquantity(int v) { *_quantity += v; }
Article getArticle() { return _Article; }
friend ostream & operator << (ostream & COUT, Item & obj);
};
ostream & operator << (ostream & COUT, Item & obj){
COUT << "quantity: " << *obj._quantity << endl << obj._Article;
return COUT;
}
First class is article with constructors, destructs and overloaded operators, second class ITEM is simple it holds article and quantity.
For test in main i have following code:
Article a;
Article b("code", "name", 1.5);
Article c(b);
cout << a;
cout << b;
c++;
c++;
c.setPrice(10);
cout << c;
cout << "\n ************************************** \n";
Item _stavke[100];
for (size_t i = 0; i < 3; i++)
{
_stavke[i].getArticle().setPrice(100);
cout << _stavke[i];
cout << "\n \t\t\t ---- \n";
}
First part of code where i test Article class and some of overloaded operators it works fine but second part where i have Item _stavke[100]; array i can list members of array - no problem but any invoked change is not accepted basicly code
_stavke[i].getArticle().setPrice(100);
does not do anything it seems ...
Can anyone point me where i am going wrong and why i can not change members of array?
Thank you in advance
Your getArticle() call returns _Article by value. That is, a copy of article. Your setPrice() is invoked on the copy, so it is not reflected in the original Item's article, which remains unchanged.

Creating a deck of Cards

Okay, first off I have looked at various of the questions that were asked about creating a deck of Cards but every single one I looked was using the vector thing, I'm not sure how to write it, cause I have not taken that subject in class so I don't know how to apply it.
The Card.H and Card.cpp are all fine, no need to change a thing in them
I need help in Deck.H and Deck.cpp.
My initialize() function is not finished and I cant seem to know how to finish it and with the other methods in the Deck class I have not tried to write any of them since I cant generate a deck of cards.
CARD.H
Class Card
{
int m_face;
char m_suit;
public:
Card(int _face = 2 , char _suit = 3);
~Card();
int GetFace() const;
char GetSuit() const;
void SetFace(int _face);
void SetSuit(char _suit);
void Show() const;
}
CARD.CPP
#include "Card.h"
Card::Card(int _face, char _suit)
{
m_face = _face;
m_suit = _suit;
}
Card::~Card()
{
}
int Card ::GetFace() const
{
return m_face;
}
char Card ::GetSuit() const
{
return m_suit;
}
void Card::SetFace(int _face)
{
m_face = _face;
}
void Card::SetSuit(char _suit)
{
m_suit = _suit;
}
void Card::Show() const
{
if (m_face == 11)
cout << " J " << m_suit << endl;
else if (m_face == 12)
cout << " Q " << m_suit << endl;
else if (m_face == 13)
cout << " K " << m_suit << endl;
else if (m_face == 14)
cout << " A " << m_suit << endl;
else
cout << m_face << m_suit << endl;
}
DECK.H
#pragma once
#include "stdafx.h"
#include "Card.h"
Class Deck
{
Card m_cards[52];
public:
Deck();
void Initialize();
void Shuffle();
bool Draw(Card& _card);
void Clear();
bool IsEmpty() const;
}
DECK.CPP
#include "Deck.h"
#include"Card.h"
void Deck::Initialize()
{
int count = 0;
char Suits[] = { 3, 4, 5, 6 };
for (int i = 0; i < 4; ++i) //Suits
{
for (int F = 2; F < 14; ++F) //faces
{
m_cards[count].SetSuit(Suits[i]);
m_cards[count].SetFace(F);
}
}
}
void Deck::Shuffle()
{
}
bool Deck::Draw(Card& _card
{
}
void Deck::Clear()
{
}
bool Deck::IsEmpty() const
{
}
I don't think your Initialize function needs much more work.
Only 2 remarks:
You forgot a ++count at the end of the inner for loop (now you're setting the same card every time).
As you wrote the inner for loop, the F variable will only be allowed to go up to 13 (because you used < 14). This means your deck won't contain any aces ... most logical thing for me would be to use <= 14 instead.
A little tweaking and it works.
#include <iostream>
#include <algorithm>
using namespace std;
class Card
{
private:
int m_face;
char m_suit;
public:
Card(int _face = 2 , char _suit = 3)
{
m_face = _face;
m_suit = _suit;
}
~Card(){}
int GetFace() const { return m_face; }
char GetSuit() const { return m_suit; }
void SetFace(int _face) { m_face = _face; }
void SetSuit(char _suit) { m_suit = _suit; }
void Show() const
{
if (m_face == 11)
cout << " J " << m_suit << endl;
else if (m_face == 12)
cout << " Q " << m_suit << endl;
else if (m_face == 13)
cout << " K " << m_suit << endl;
else if (m_face == 14)
cout << " A " << m_suit << endl;
else
cout << m_face << m_suit << endl;
}
};
class Deck
{
private:
Card m_cards[52];
int current;
public:
Deck() { Initialize(); }
void Initialize()
{
current = 51;
int count = 0;
char Suits[] = { 3, 4, 5, 6 };
for (int i = 0; i < 4; ++i) //Suits
{
for (int F = 2; F <= 14; ++F) //faces
{
m_cards[count++].SetSuit(Suits[i]);
m_cards[count++].SetFace(F);
}
}
}
void Shuffle() { std::random_shuffle(m_cards, m_cards + current + 1); }
bool Draw(Card& _card)
{
if (IsEmpty()) return false;
_card = m_cards[current--];
return true;
}
void Clear() { current = -1; }
bool IsEmpty() const { return current < 0; }
};
int main()
{
Deck deck;
while(!deck.IsEmpty())
{
Card c;
deck.Draw(c);
c.Show();
}
return 0;
}