A class that contains a member of the same class - c++

I would Like to construct a class that contains itself but I have to avoid an endless loop. For example I started of my class
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class box {
protected:
int id;
vector<box*> intmega;
int n = 10;
public:
box(box const& autre, int id) : n(autre.n), id(id) {
for (auto& element : autre.get_intmega()) {
intmega.push_back(new box(*element, id + 100));
}
cout << "A new object has seen light" << endl;
}
box(int id) : n(10), id(id) { cout << "Created Box" << endl; }
void ajoute2(box& autre) { intmega.push_back(new box(autre)); }
int size_() const { return intmega.size(); }
int number() const { return n; }
box* get() { return intmega[0]; }
vector<box*> get_intmega() const { return intmega; }
int getId() const { return id; }
~box() {
cout << this << endl;
for (auto element : this->intmega)
delete element;
}
};
void affichel(box const& autre) {
cout << "Box :" << autre.getId() << endl;
cout << "Box :" << &autre << endl;
}
void affiche(box& autre) {
for (auto* element : autre.get_intmega()) {
affichel(*element);
affiche(*element);
cout << endl;
}
}
int main() {
box box1(1);
box box2(2);
box box3(3);
box2.ajoute2(box3);
box1.ajoute2(box2);
box box4(box1, 4);
affiche(box1);
cout << "Box1 Address : " << &box1 << endl;
affiche(box4);
cout << "Box4 Address : " << &box4 << endl;
return 0;
}
Everything works fine but upon calling the destructor disaster.
It deletes all objects but it gets into an endless loop of deleting an object that has already been deleted. Any suggestions help?

I made those slight modifications and now my program works just fine.
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class box
{
protected:
vector<box*> intmega;
int n = 10;
public:
box(box const &autre) : n(autre.n)
{
for (auto &element : autre.get_intmega())
{
intmega.push_back(new box(*element));
}
cout << "A new object has seen light" << endl;
cout<<this<<endl;
}
box()
{
cout << "Created Box" << endl;
cout<<this<<endl;
}
void ajoute2(box & autre){
intmega.push_back(new box(autre));
}
int size_() const
{
return intmega.size();
}
int number() const
{
return n;
}
vector<box *> get_intmega() const
{
return intmega;
}
~box()
{
cout<<this<<endl;
for(auto element: this->intmega){
delete element;
}
}
};
void affichel(box const &autre)
{
cout << "Box :" << &autre<< endl;
}
void affiche(box &autre)
{
for (auto *element : autre.get_intmega())
{
affichel(*element);
affiche(*element);
cout << endl;
}
}
int main()
{
box box1;
box box2;
box box3;
box box4;
box3.ajoute2(box4);
box2.ajoute2(box3);
box1.ajoute2(box2);
box box5(box1);
affiche(box1);
cout << "Box1 Address : " << &box1 << endl ;
affiche(box5);
cout << "Box5 Address : " << &box4 << endl ;
return 0;
}

Related

how to compare strings in vector in c++?

hey I have class containing
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <iomanip>
using namespace std;
struct student
{
std::string ID;
std::string Name;
std::vector<std::string> friends;
};
And main function contains
int main() {
vector<student> List_Students = { { "d123", "Jacob", {"e321"} }, { "e321", "Abo", {"d123", "e456"} }, { "e456","Mark",{} } };
for (auto& s : List_Students)
{
cout << s.ID << "\t" << s.Name;
for (auto& f : s.friends)
{
cout << " " << f << " ";
}
cout << endl;
}
}
this yields output as expected
output:
d123 Jacob e321
e321 Abo d123 e456
e456 Mark
my question is how can I compare the vector of friends with IDs so that so that after it shows friends it shows their names with it. Expected output:
d123 Jacob e321 (Abo)
e321 Abo d123 (Jacob) e456 (Mark)
e456 Mark (No friends)
quite new to c++ any help would be appreciated thank you
You can use the standard std::find_if() algorithm, eg
...
#include <algorithm>
...
int main() {
vector<student> List_Students = {
{ "d123", "Jacob", {"e321"} },
{ "e321", "Abo", {"d123", "e456"} },
{ "e456", "Mark", {} }
};
for (auto& s : List_Students)
{
cout << s.ID << "\t" << s.Name;
if (s.friends.empty())
{
cout << " (No friends)";
}
else
{
for (auto& f : s.friends)
{
cout << " " << f << " ";
auto iter = find_if(List_Students.begin(), List_Students.end(),
[&](const student &s2){ return s2.ID == f; }
);
if (iter != List_Students.end())
{
cout << "(" << iter->Name << ") ";
}
}
}
cout << endl;
}
}
Or, like #Ch3steR said in comments, you can store the names in a std::map:
...
#include <map>
#include <utility>
...
int main() {
vector<student> List_Students = {
{ "d123", "Jacob", {"e321"} },
{ "e321", "Abo", {"d123", "e456"} },
{ "e456", "Mark", {} }
};
map<string, string> names;
for (auto& s : List_Students)
{
names.insert(make_pair(s.ID, s.Name));
}
for (auto& s : List_Students)
{
cout << s.ID << "\t" << s.Name;
if (s.friends.empty())
{
cout << " (No friends)";
}
else
{
for (auto& f : s.friends)
{
cout << " " << f << " (" << names[f] << ") ";
}
}
cout << endl;
}
}
Alternatively:
#include <iostream>
#include <string>
#include <map>
using namespace std;
struct student
{
string Name;
vector<string> friends;
};
int main() {
map<string, student> List_Students = {
{ "d123", { "Jacob", {"e321"} } },
{ "e321", { "Abo", {"d123", "e456"} } },
{ "e456", { "Mark", {} } }
};
for (auto& elem : List_Students)
{
auto &s = elem.second;
cout << elem.first << "\t" << s.Name;
if (s.friends.empty())
{
cout << " (No friends)";
}
else
{
for (auto& f : s.friends)
{
cout << " " << f << " (" << List_Students[f].Name << ") ";
}
}
cout << endl;
}
}

How to change variable stored in parent class from an inherited class in C++

So as the title suggests I am attempting to change the number variable, originally stored as 1000. Change this variable in another class function, and then replace the original value (1000) with the newly updated number. I haven't been able to find anything online to help me with this.
I have tried using pointers to no avail.
#include <iostream>
using namespace std;
class data {
protected:
int number = 1000;
};
class fetchData : public data {
public:
int getNumber() {
return number;
}
int updateNumber(int newNumber) {
number = newNumber;
return number;
}
};
class function : public fetchData {
public:
void minusNumber(int numberTakeAway) {
int newNumber = number - numberTakeAway;
updateNumber(newNumber);
cout << "Taken away: " << numberTakeAway << endl;
cout << "\nShould be new number: " << number << endl; // Not updating parent class variable
}
};
void printData() {
fetchData r;
cout << "number: " << r.getNumber() << endl;
}
void minusNumber() {
function r;
r.minusNumber(200);
}
int main(void) {
fetchData q;
cout << "\nOriginal ";
printData();
cout << "\n";
minusNumber();
cout << "\nActual ";
printData();
cout << "\n";
return 0;
}
You seem to be confusing between static - class members, and non static - instance members.
number is an instance member which means every instance will have its own number with its own value.
Each of your functions main, printData, and minusNumber creates its own instance of function or fetchData class, and there is no connection between them.
Try this code, where there is only one instance:
int main(void) {
function q;
cout << "\nOriginal ";
q.printData();
cout << "\n";
q.minusNumber(200);
cout << "\nActual ";
q.printData();
cout << "\n";
return 0;
}
What you have done in the free functions is to create a new instance of your class. If you want to do something with q that you instantiated in main, you have to pass it. Or use the member function in your class. So below, I've changed printData to take a reference to q. And instead of calling the free function minusNumber, I've called the member function of your class. I deleted the free function as it is not used.
#include <iostream>
class data {
protected:
int number = 1000;
};
class fetchData : public data {
public:
int getNumber() const {
return number;
}
int updateNumber(int newNumber) {
number = newNumber;
return number;
}
};
class function : public fetchData {
public:
void minusNumber(int numberTakeAway) {
int newNumber = number - numberTakeAway;
updateNumber(newNumber);
std::cout << "Taken away: " << numberTakeAway << std::endl;
std::cout << "\nShould be new number: " << number << std::endl; // Not updating parent class variable
}
};
void printData(const function& r) {
std::cout << "number: " << r.getNumber() << std::endl;
}
int main(void) {
function q;
std::cout << "\nOriginal ";
printData(q);
std::cout << "\n";
q.minusNumber(200);
std::cout << "\nActual ";
printData(q);
std::cout << "\n";
return 0;
}

Trouble with modifying object values in a c++ vector

I am trying to develop an inventory system for a game in c++. I have 2 header files one is named item and the other inventory these are sent into my main method. The way I have my code set up is when I send an Item object to my inventory the inventory checks to see if an object with the same ID exists. If it does then get the quantity Item value and increment it by one. The problem is the change to the Quantity value does not save to the main Inventory object. Any and all help would be very appreciated. Also sorry if my code is bad! I am not going to include all the code, and I am sure that all the proper #include functions are in!
The real issue seems to be somewhere in the actual new Quantity value not being added to the main Inventory object.
#include "stdafx.h"
#include <iostream>
#include "Windows.h"
#include "Item.h"
#include "Inventory.h"
#include <ctime>
#include <fstream>
#include <conio.h>
#include <stdio.h>
#include <windows.h>
#include <string>
#include <cstdio>
#include <vector>
// Functions!
void gotoxy(int x, int y)
{
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void setColor(int color) // 0 Black, 1 Blue, 2 Green, 3 Light Blue, 4Red 5 Purple 6 Yellow 7 White
{
HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, color);
}
void clearColor()
{
HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, 7);
}
void ShowConsoleCursor(bool showFlag)
{
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cursorInfo;
GetConsoleCursorInfo(out, &cursorInfo);
cursorInfo.bVisible = showFlag; // set the cursor visibility
SetConsoleCursorInfo(out, &cursorInfo);
}
//
// Menu SetUp!
void menuArea()
{
gotoxy(40, 4);
setColor(2);
std::cout << "--------Menu--------" << std::endl;
gotoxy(40, 12);
std::cout << "--------------------" << std::endl;
clearColor();
}
void gatherArea()
{
gotoxy(45, 6);
setColor(3);
std::cout << "-Gather" << std::endl;
clearColor();
}
void recoveryArea()
{
gotoxy(45, 8);
setColor(5);
std::cout << "-Recovery" << std::endl;
clearColor();
}
void inventoryArea()
{
gotoxy(45, 10);
setColor(4);
std::cout << "-Inventory" << std::endl;
clearColor();
}
//
// Menu Selector!
void gatherOption()
{
gotoxy(40, 6);
std::cout << "(G)" << std::endl;
}
void recoverOption()
{
gotoxy(40, 8);
std::cout << "(R)" << std::endl;
}
void inventoryOption()
{
gotoxy(40, 10);
std::cout << "(I)" << std::endl;
}
void gatherSelected()
{
setColor(5);
gotoxy(40, 6);
std::cout << "(G)" << std::endl;
clearColor();
}
void recoverSelected()
{
setColor(5);
gotoxy(40, 8);
std::cout << "(R)" << std::endl;
clearColor();
}
void inventorySelected()
{
setColor(5);
gotoxy(40, 10);
std::cout << "(I)" << std::endl;
clearColor();
}
//
// Menu Viewer!
void viewClear()
{
gotoxy(0, 4);
for (int i = 0; i < 40; i++)
{
std::cout << "\t\t\t\t\t" << std::endl;
}
}
void viewGather()
{
gotoxy(12, 4);
std::cout << "-----Gather-----\n" << std::endl;
std::cout << "\t 1) Gather Wood (5 sec)\n" << std::endl;
std::cout << "\t 2) Gather Berries (5 sec)\n" << std::endl;
}
void viewRecover()
{
gotoxy(12, 4);
std::cout << "-----Recover-----\n" << std::endl;
std::cout << "\t 1) Eat Berries (5 sec)\n" << std::endl;
std::cout << "\t 2) Sleep (10 sec)\n" << std::endl;
}
//
// Figuring out the inventory
void viewInventory(Inventory inventory)
{
std::string inv = inventory.display(inventory);
gotoxy(12, 4);
std::cout << inv << std::endl;
}
Inventory setInventory(Inventory inventory)
{
Item woodItem(1, "Wood;");
Item berriesItem(2, "Berries");
inventory.addItem(woodItem);
inventory.addItem(berriesItem);
return inventory;
}
//
//Timer Stuff!
void timerSetup()
{
setColor(6);
gotoxy(5, 2);
std::cout << "Client Up Time:" << std::endl;
clearColor();
}
void getUpTime()
{
gotoxy(22, 2);
int seconds = (int)std::clock() / 1000;
int minutes = (int)seconds / 60;
seconds = seconds % 60;
if (seconds < 10 && minutes < 10)
std::cout << "0" << minutes << ":0" << seconds << std::endl;
else if (seconds < 10)
std::cout << minutes << ":0" << seconds << std::endl;
else if (minutes<10)
std::cout << "0" << minutes << ":" << seconds << std::endl;
else
std::cout << minutes << ":" << seconds << std::endl;
}
//
void drawMenu()
{
menuArea();
gatherArea();
recoveryArea();
inventoryArea();
timerSetup();
gatherOption();
recoverOption();
inventoryOption();
}
int main()
{
Inventory inventory;
drawMenu();
std::clock_t start;
inventory = setInventory(inventory);
while (true)
{
ShowConsoleCursor(false);
getUpTime();
if (GetAsyncKeyState(0x47)) //G
{
gatherSelected();
recoverOption();
inventoryOption();
viewClear();
viewGather();
}
if (GetAsyncKeyState(0x52))//R
{
recoverSelected();
gatherOption();
inventoryOption();
viewClear();
viewRecover();
}
if (GetAsyncKeyState(0x49))//I
{
Item admin(0, "Test");
inventory.addItem(admin);
inventorySelected();
gatherOption();
recoverOption();
viewClear();
Item bannana(3, "Bannana");
inventory.addItem(bannana);
viewInventory(inventory);
}
if (GetAsyncKeyState(VK_ESCAPE))//Esc
{
inventoryOption();
gatherOption();
recoverOption();
viewClear();
}
}
}
Item.h File!
#include <string>
#pragma once
class Item
{
public:
int getId();
int getQuantity();
std::string getName();
void setQuantity(int set);
Item(int id, std::string name);
private :
int id;
std::string name;
int quantity;
};
Item::Item(int id, std::string name)
{
Item::id = id;
Item::name = name;
}
int Item::getQuantity()
{
return quantity;
}
int Item::getId()
{
return id;
}
std::string Item::getName()
{
return name;
}
void Item::setQuantity(int set)
{
quantity = set;
}
Inventory.h Header File!
#include "Item.h"
#include <vector>
#include <iostream>
#pragma once
class Inventory
{
public:
Inventory();
std::vector<Item> inventory;
void addItem(Item item);
std::string display(Inventory inventory);
};
Inventory::Inventory()
{
}
void Inventory::addItem(Item item)
{
int id = item.getId();
boolean added = false;
for (Item check : Inventory::inventory)
{
if (id == check.getId())
{
int x = check.getQuantity();
x++;
check.setQuantity(x);
std::cout << "Check!" << check.getQuantity() << check.getName();
added = true;
}
}
if (!added)
{
item.setQuantity(0);
Inventory::inventory.push_back(item);
}
}
std::string Inventory::display(Inventory inventory)
{
std::string display = "---Inventory---\n";
display += "\n--------------------------------------\n";
if (Inventory::inventory.size()== 0)
return display;
else
{
for (Item item : Inventory::inventory)
{
display += " Name: " + item.getName();
display += " Id: " + std::to_string(item.getId());
display += " Quantity: " + std::to_string(item.getQuantity());
display += "\n--------------------------------------\n";
}
return display;
}
}
Your issue is in this line:
for (Item check : Inventory::inventory)
You modify check, but check is a copy of items in your inventory! Loop through with check being a reference instead:
for (Item &check : Inventory::inventory)
^^^
Also, when you first get an item, you set its quantity to 0:
item.setQuantity(0);
Is this intentional? Perhaps you mean to set it to 1 instead:
item.setQuantity(1);
Or even better, add a set to 1 in the constructor! (after all, when an item is made it's because we have at least one of it, right?). And while your at it, you can switch to a field initialization list with your constructors to make life easier as well:
Item::Item(int id, std::string name) : id(id), name(name), quantity(1) { }

C++ print out objects error

I am getting stuck on print the object Meja1 and Meja2 into class Informasi.
How I can print the object Meja1.print_Meja(); and Meja2.print_Meja();
and please advice me how I can write my code into human readable coding style?
#include <iostream>
#include <string.h>
using namespace std;
class Inventaris {
private:
string Jenis;
string Warna;
string Keadaan;
public:
void setInventaris (string a, string u, string g)
{
Jenis=a;
Warna=u;
Keadaan=g;
}
string getJenis()
{
return Jenis;
}
string getWarna()
{
return Warna;
}
string getKeadaan()
{
return Keadaan;
}
void cetak ()
{
cout<<"Info Inventaris adalah :"<<endl;
cout<<"Jenis : "<<getJenis()<<endl;
cout<<"Warna : "<<getWarna()<<endl;
cout<<"Keadaan : "<<getKeadaan()<<endl;
}
};
class Kursi : public Inventaris {
public:
void print_Kursi(){
hitung++;
cout << "Informasi kursi adalah" <<endl;
cout<<"Jenis : "<<getJenis()<<endl;
cout<<"Warna : "<<getWarna()<<endl;
cout<<"Keadaan : "<<getKeadaan()<<endl;
}
static int hitung;
static getHitung()
{
return hitung;
}
};
class Meja : public Inventaris {
public:
void print_Meja(){
cout << "Informasi Meja adalah" <<endl;
cout<<"Jenis : "<<getJenis()<<endl;
cout<<"Warna : "<<getWarna()<<endl;
cout<<"Keadaan : "<<getKeadaan()<<endl;
hitung_meja++;
}
static int hitung_meja;
static getHitung_meja()
{
return hitung_meja;
}
};
class Informasi : public Meja, public Kursi {
public:
void print_info(){
cout << "Informasi" <<endl;
cout << "Jumlah Meja = " << Meja::getHitung_meja() << endl;
Meja1.print_Meja(); // how I print object Meja1 and Meja2
Meja2.print_Meja();
cout << "Jumlah Kursi = " << Kursi::getHitung() << endl;
}
};
int Kursi::hitung = 0;
int Meja::hitung_meja = 0;
int main() {
Kursi Kursi1;
Kursi1.setInventaris("Kursi goyang","Merah muda", "Bekas");
Kursi1.print_Kursi();
cout << endl;
Kursi Kursi2;
Kursi2.setInventaris("Kursi kakek","reyot", "Bekas");
Kursi2.print_Kursi();
cout << endl;
Meja Meja1;
Meja1.setInventaris("Meja Antik","Coklat tua","Bekas");
Meja1.print_Meja();
cout << endl;
Meja Meja2;
Meja2.setInventaris("Meja Coffee","Hijau Robek","Bekas");
Meja2.print_Meja();
cout << endl;
Informasi info;
info.print_info();
}
I fixed your code and I made Meja1 and Meja2 global declarations so they are accessible by main() and Informasi class.
#include <iostream>
#include <string>
using namespace std;
class Inventaris {
private:
string Jenis;
string Warna;
string Keadaan;
public:
void setInventaris(string a, string u, string g)
{
Jenis = a;
Warna = u;
Keadaan = g;
}
string getJenis()
{
return Jenis;
}
string getWarna()
{
return Warna;
}
string getKeadaan()
{
return Keadaan;
}
void cetak()
{
cout << "Info Inventaris adalah :" << endl;
cout << "Jenis : " << getJenis() << endl;
cout << "Warna : " << getWarna() << endl;
cout << "Keadaan : " << getKeadaan() << endl;
}
};
class Kursi : public Inventaris {
public:
void print_Kursi() {
hitung++;
cout << "Informasi kursi adalah" << endl;
cout << "Jenis : " << getJenis() << endl;
cout << "Warna : " << getWarna() << endl;
cout << "Keadaan : " << getKeadaan() << endl;
}
static int hitung;
static int getHitung() // <--- FIXED!
{
return hitung;
}
};
class Meja : public Inventaris {
public:
void print_Meja() {
cout << "Informasi Meja adalah" << endl;
cout << "Jenis : " << getJenis() << endl;
cout << "Warna : " << getWarna() << endl;
cout << "Keadaan : " << getKeadaan() << endl;
hitung_meja++;
}
static int hitung_meja;
static int getHitung_meja() // <--- FIXED!
{
return hitung_meja;
}
};
Meja Meja1; // <--- Global declaration accessible by main() and Informasi
Meja Meja2; // <--- Global declaration accessible by main() and Informasi
class Informasi : public Meja, public Kursi {
public:
void print_info() {
cout << "Informasi" << endl;
cout << "Jumlah Meja = " << Meja::getHitung_meja() << endl;
Meja1.print_Meja();
Meja2.print_Meja();
cout << "Jumlah Kursi = " << Kursi::getHitung() << endl;
}
};
int Kursi::hitung = 0;
int Meja::hitung_meja = 0;
int main() {
Kursi Kursi1;
Kursi1.setInventaris("Kursi goyang", "Merah muda", "Bekas");
Kursi1.print_Kursi();
cout << endl;
Kursi Kursi2;
Kursi2.setInventaris("Kursi kakek", "reyot", "Bekas");
Kursi2.print_Kursi();
cout << endl;
Meja1.setInventaris("Meja Antik", "Coklat tua", "Bekas");
Meja1.print_Meja();
cout << endl;
Meja2.setInventaris("Meja Coffee", "Hijau Robek", "Bekas");
Meja2.print_Meja();
cout << endl;
Informasi info;
info.print_info();
}

Access Elements of Vector - C++

I have the following class:
class Friend
{
public:
Friend();
~Friend(){}
void setName(string friendName){ name = friendName; }
void setAge(int friendAge) { age = friendAge; }
void setHeight(int friendHeight) { height = friendHeight; }
void printFriendInfo();
private:
string name;
int age;
float height;
};
//implementations
Friend::Friend()
{
age = 0;
height = 0.0;
}
//printing
void Friend::printFriendInfo()
{
cout << "Name : " << name << endl;
cout << "Age : " << age << endl;
cout << "Height : " << height << endl << endl;
}
And At this moment I can introduce the values in a vector, like this:
std::vector<Friend> regist(4, Friend());
regist[1].setAge(15);
regist[1].setHeight(90);
regist[1].setName("eieiei");
regist[2].setAge(40);
regist[2].setHeight(85);
regist[2].setName("random");
In debug, this solution works fine. But now I am trying to print the vector. So far without success.
for (int i = 0; i < regist.size(); i++) {
cout << regist[i]; //<-- error here
cout << '\n';
}
You might redesign a bit (in essence):
#include <iostream>
class Friend
{
public:
Friend();
// A more general name, const, and taking a stream.
void write(std::ostream&) const;
private:
std::string name;
int age;
float height;
};
Friend::Friend()
{
age = 0;
height = 0.0;
}
void Friend::write(std::ostream& stream) const
{
stream << "Name : " << name << std::endl;
stream << "Age : " << age << std::endl;
stream << "Height : " << height << std::endl << std::endl;
}
// Forward to the member function
inline std::ostream& operator << (std::ostream& stream, const Friend& object) {
object.write(stream);
return stream;
}
int main() {
Friend f;
std::cout << f;
}
Just call the printFriendInfo() member function:
for (int i = 0; i < regist.size(); i++) {
regist[i].printFriendInfo();
}
For
cout << regist[i];
to work, add a few accessor functions in Friend
string getName() const { return name; }
int getAge() const { return age; }
float getHeight() const { return height; }
and implement an overloaded operator<< function:
std::ostream& operator<<(std::ostream& out, Friend const& f)
{
out << "Name : " << f.getName() << std::endl;
out << "Age : " << f.getAge() << std::endl;
out << "Height : " << f.getHeight() << std::endl;
return out;
}