how to specify an object without using its attributes - c++

I am learning object oriented programming.
To know which object is being destroyed, I want to add some code in the destructor of a class and use an attribute to do it.
For example-
class player{
public:
string name;
int health;
~player(){
cout<<name<<" destroyed";
}
};
In this example, name correctly helps me identify the object which is being destroyed.
But if there weren't any such attributes which could help me know which object was being destroyed, what should be done.
Is there a way to print the object's name itself. ( i.e. if I create a player enemy; then enemy is what I mean to say by name)

If you want it to be versatile, you can overload operator << instead of focusing solely on the destructor and outputting bits and pieces of your class attributes.
Here is an example:
#include <string>
#include <ostream>
#include <iostream>
class player {
std::string name;
int health;
public:
player(const std::string& n, int h) : name(n), health(h) {}
~player() { std::cout << "Destroying the following: " << *this << "\n"; }
friend std::ostream& operator << (std::ostream& os, const player& p);
};
std::ostream& operator << (std::ostream& os, const player& p)
{
os << p.name << " " << p.health;
return os;
}
int main()
{
player p1("Joe", 1);
player p2("Sam", 2);
std::cout << p1 << "\n" << p2 << "\n";
}
Output:
Joe 1
Sam 2
Destroying the following: Sam 2
Destroying the following: Joe 1
You can follow what was done by looking at some documentation here.

Related

How to display an array of objects derived from a base class, each with it's own different operator overload function?

So i have a base class, and 3 derived classes, and another class template which as a parameter is given the base class, class template has an array of the 3 different type of objects. I have overloaded the << operator for all 3 derived classes and the base class, but when i try to display all the array in the console, the base class operator overload function is used, how do i make it in such a way that when i iterate through the array of objects and display each one, it's different for every type of object?
base class representation
#pragma once
#include <iostream>
#include <string>
class Sushi
{
private:
static int count;
protected:
int id;
int cost;
std::string fish_type;
public:
Sushi();
Sushi(int cost, std::string fish_type);
~Sushi();
int get_id();
int get_cost();
std::string get_ftype();
void set_cost(int cost);
void set_ftype(std::string fish);
friend std::ostream& operator<<(std::ostream& os, const Sushi& sushi);
};
base class operator
std::ostream& operator<<(std::ostream& os, const Sushi& sushi)
{
os << sushi.id << " " << sushi.cost << " " << sushi.fish_type << std::endl;
return os;
}
class template representation
#pragma once
#include "Sushi.h"
template <class Sushi>
class SushiRepository
{
Sushi *repo;
int capacity;
int top;
public:
//default constructor
SushiRepository();
//constructor
SushiRepository(int size);
//adds an element to top of the stack
void push(Sushi s);
//Pops an element from the top of the stack and returns it
Sushi pop();
//Returns the last element from the top of the stack
Sushi peek();
//returns the size of the repo
int size();
//checks if repo is empty
bool isEmpty();
//checks if repo is full
bool isFull();
//remove by id
void removeByID(int id);
//display all
void displayAll();
~SushiRepository();
};
class template display function
template <class Sushi>
inline void SushiRepository<Sushi>::displayAll()
{
if (!isEmpty()) {
for (int i = 0; i < size(); i++)
{
std::cout << repo[i] << std::endl;
}
}
else {
std::cout << "Repo is empty";
}
}
template<class Sushi>
SushiRepository<Sushi>::~SushiRepository()
{
delete[] repo;
}
derived class representation
#pragma once
#include "Sushi.h"
#include <ostream>
class Sashimi : public Sushi
{
std::string bed;
public:
Sashimi();
Sashimi(std::string bed);
~Sashimi();
std::string get_bed();
void set_bed(std::string b);
friend std::ostream &operator<<(std::ostream &os, const Sashimi &sh);
};
one of the derived classes operator overload function
std::ostream& operator<<(std::ostream& os, const Sashimi& sh)
{
os << "ID:" << sh.id << " Sashimi of " << sh.fish_type << " on a bed of: " << sh.bed << " cost: " << sh.cost << std::endl;
return os;
}

Utilizing constructor, destructor, and printing off objects - c++

Read the comments too.
Basically, I am trying to figure out object constructors, destructor, and classes. I created a class with a few public member variables, and a few private member variables. At this point I am only utilizing the public members within my code.
My question is, to put it quite simply, how do I utilize the constructor, destructor, and print off the objects info to the console.
Thanks.
#include <iostream>
// Class -> NPC
// Contains generic stats for an NPC in a game
class NPC
{
public:
char name;
int age;
char favoriteItem;
private:
char quest;
char nemesis;
int karma;
}
// Object Constructor
NPC::NPC (char newName, int newAge, char newFavoriteItem)
{
name = newName;
age = newAge;
favoriteItem = newFavoriteItem;
}
// Object Deconstructor
NPC::~NPC()
{
// Do nothing
}
// Here I would like to create a new NPC, bob, with a name of "Bob", age of 28, and his favorite items being a Sword
// Next, I attempt to use this information as output.
int main()
{
NPC bob("Bob",28, "Sword");
std::cout << bob << std::endl;
}
Fixed the char (only one character) to std::string. I added initialization list and std::ostream &operator << operator.
http://en.cppreference.com/w/cpp/language/default_constructor
#include <iostream>
#include <memory>
#include <string.h>
class NPC
{
public:
std::string name;
int age;
std::string favoriteItem;
NPC(std::string const& name, int age, std::string favoriteItem)
: name(name), age(age), favoriteItem(favoriteItem)
{};
private:
char quest;
char nemesis;
int karma;
};
std::ostream &operator << (std::ostream &os, NPC const& npc)
{
os << npc.name << " " << npc.age << " " << npc.favoriteItem << "\n";
return os;
};
int main()
{
NPC npc("Bob", 28, "Sword");
std::cout << npc;
return 0;
}

Using Member Variables That Are Private c++

I added all my code.
The exact problem I am facing is when I make the member variables private in the game.h file I get an error in the game.cpp file that says n p h are all private members of game.h. in Xcode.
But when I compile the program from the command line it compiles fine with no errors.
I am trying to understand if I am doing something wrong or is this up to standards the way I am doing this?
This is main.cpp
#include "game.h"
int main() {
game g("Female", "Magic", true, 21, 5, 120);
std::cout << "These are the things every game needs to be a game" << '\n';
std::cout << g << '\n';
return 0;
}
game.cpp
#include <iostream>
#include "game.h"
std::ostream& operator<<(std::ostream& s, const game& g) {
return s << &g.n << ' ' << &g.p << ' ' << &g.h;
}
This is my composite class
#include <iostream>
#include "npc.h"
#include "pc.h"
#include "health.h"
class game {
private:
npc n;
pc p;
health h;
public:
game(const npc& init_n, const pc& init_p, const health& init_h):
n(init_n),
p(init_p),
h(init_h)
{}
game(std::string gen, std::string abil, bool use, int lvl, int h, int arm) :
n(gen, abil),
p(use, lvl),
h(h, arm)
{
}
friend std::ostream& operator<<(std::ostream& s, const game& g) {
g.n.output(s);
g.p.output(s);
g.h.output(s);
return s;
}
npc get_n() { return n; }
pc get_p() { return p; }
health get_h() { return h; }
void set_n(npc init_n) { n = init_n; }
void set_p(pc init_p) { p = init_p ; }
void set_h(health init_h) { h = init_h; }
};
Here is a class
#include <iostream>
class health {
private:
int hp;
int armor;
public:
health(int init_hp, int init_armor) :
hp(init_hp),
armor(init_armor)
{
}
public:
void output(std::ostream& s) const { s << "Characters have this amount of hit points "<< hp << " and an armor rating of " << armor << "\n"; }
};
Here is a class
class pc {
private:
bool user;
int level;
public:
pc(bool init_user, int init_level) :
user(init_user),
level(init_level)
{
}
public:
void output(std::ostream& s) const { s << "A player character has at least "<< user << " user and a level of " << level << '\n'; }
};
Here is a class
#include <iostream>
class npc {
private:
std::string gender;
std::string ability;
public:
npc(std::string init_gender, std::string init_ability) :
gender(init_gender),
ability(init_ability)
{
}
public:
void output(std::ostream& s) const { s << "A non player character has a gender of "<< gender << " and an ability of " << ability << '\n'; }
};
You made several errors - a typo is the reason for your problem.
The function is not allowed to access those members because it is not a friend of the class.
The friend is (correctly) std::ostream& operator<<(std::ostream& s, const game& g)
while you defined a function std::ostream& operator<<(std::ostream& s, const game g), note the missing ampersand.
Also, your accessors should be const, and return a const reference.
Ie,
npc const& get_n() const { return n; }
pc const& get_p() const { return p; }
health const& get_h() const { return h; }
Your manipulators change the wrong variables! You change the ones passed to the function instead of the members of that class.... However, it is highly questionable that you add direct manipulators for the three private members. You must view your class as some abstract object and define operators that work on that object. If you just give direct access to all it's members than there is little left of the object orientation idea behind using a class with private members (this would still be ten times better than making them public though!)
Finally, just a coding style hint. It is common practice to use CamelCase names for custom classes (ie, class Game), and you're better of adding a prefix to your private members to distinguish them from function parameters. Often people use the prefix m_. You really should use complete english words too (not abbreviations, let alone single characters).
This would turn your code into, say...
class Game {
private:
Npc m_npc;
Pc m_pc;
Health m_health;
public:
Game(Npc const& npc, Pc const& pc, Health const& health) :
m_npc(npc), m_pc(pc), m_health(health) { }
etc.

how to overload << operator for YAML::Emitter to serialize a custom class containing vector of another custom class

In my application, I have a class that contains a vector of another class and I am unable to write overloaded YAML::Emitter& operator<< for this.
To illustrate, I have written the bellow file which reproduces the error:
class Department contains a vector of Employee and I need to output the Department with all employees in Yaml format.
I get the following weird error that does not seem to match my method signatures:
$ g++ ta.cpp -L ~/yaml-cpp/lib/ -I ../Thanga/yaml/yaml-cpp-0.5.1/include/ -lyamlcpp 2>&1|more
...
ta.cpp:37:16: note: YAML::Emitter& operator<<(YAML::Emitter&, Department&)
ta.cpp:37:16: note: no known conversion for argument 2 from ‘const Employee’ to ‘Department&’
ta.cpp:28:16: note: YAML::Emitter& operator<<(YAML::Emitter&, Employee&)
ta.cpp:28:16: note: no known conversion for argument 2 from ‘const Employee’ to ‘Employee&’
Here is the complete source file:
#include <iostream>
#include <fstream>
#include "yaml-cpp/yaml.h"
#include <cassert>
#include <vector>
#include <string>
struct Employee
{
std::string name;
std::string surname;
int age;
std::string getName(){return name;}
std::string getSurname(){return surname;}
int getAge(){return age;}
};
struct Department
{
std::string name;
int headCount;
std::vector<Employee> staff;
std::string getName(){return name;}
int getHeadCount(){return headCount;}
std::vector<Employee> & getStaff(){return staff;}
};
YAML::Emitter& operator << (YAML::Emitter& out, Employee& e) {
out << YAML::BeginMap;
out << YAML::Key <<"name"<<YAML::Value <<e.getName();
out << YAML::Key <<"surname"<<YAML::Value <<e.getSurname();
out << YAML::Key <<"age"<<YAML::Value <<e.getAge();
out << YAML::EndMap;
return out;
}
YAML::Emitter& operator << (YAML::Emitter& out, Department& d) {
out << YAML::BeginMap;
out << YAML::Key <<"name"<<YAML::Value <<d.getName();
out << YAML::Key <<"headCount"<<YAML::Value <<d.getHeadCount();
out << YAML::Key <<"Employees"<<YAML::Value <<d.getStaff();
out << YAML::EndMap;
return out;
}
int main()
{
Employee k;
Department d;
d.name="Twidlers";
d.headCount=5;
k.name="harry";
k.surname="person";
k.age=70;
d.staff.push_back(k);
k.name="joe";
k.surname="person";
k.age=30;
d.staff.push_back(k);
k.name="john";
k.surname="doe";
k.age=50;
d.staff.push_back(k);
std::ofstream ofstr("output.yaml");
YAML::Emitter out;
out<<d;
ofstr<<out.c_str();
}
The overloads provided for vector take a const std::vector<T>&, so you'll have to sprinkle some extra consts throughout:
YAML::Emitter& operator << (YAML::Emitter& out, const Employee& e)
...
YAML::Emitter& operator << (YAML::Emitter& out, const Department& d)
and then put them on your member functions, e.g.:
const std::vector<Employee>& getStaff() const { return staff; }
(In general, you should make your getters const by default, and if you need to mutate state, add setters instead of non-const getters.)

What undesirable results occur when casting to parent class object instead of reference?

This code was written by Bruce Eckel in his book "Thinking in C++" Chapter 14 page 649. What I didn't understand was the comment he made below [emphasis added]:
The operator<< for Child is interesting because of the way that it calls the operator<< for the Parent within it : by casting the Child object to a Parent&
(if you cast to a base-class object instead of a reference you will usually get undesirable results).
Here's the corresponding code:
#include <iostream>
using namespace std;
class Parent
{
int i;
public:
Parent(int ii) : i(ii) { cout << "Parent(int ii)\n"; }
Parent(const Parent& b) : i(b.i) { cout << "Parent(const Parent&)\n"; }
Parent() : i(0) { cout << "Parent()\n"; }
friend ostream& operator<<(ostream& os, const Parent& b) {
return os << "Parent: " << b.i << endl;
}
};
class Member
{
int i;
public:
Member(int ii) : i(ii) { cout << "Member(int ii)\n"; }
Member(const Member& m) : i(m.i) { cout << "Member(const Member&)\n"; }
friend ostream& operator<<(ostream& os, const Member& m) {
return os << "Member: " << m.i << endl;
}
};
class Child : public Parent
{
int i;
Member m;
public:
Child(int ii) : Parent(ii), i(ii), m(ii) { cout << "Child(int ii)\n"; }
friend ostream& operator<<(ostream& os, const Child& c) {
return os << (Parent&)c << c.m << "Child: " << c.i << endl;
}
};
int main()
{
Child c(2);
cout << "calling copy-constructor: " << endl;
Child c2 = c;
cout << "values in c2:\n" << c2;
}
That's probably object slicing meant. That is, you'll lose some parts of your object by copying it into an instance of the parent class (instead of assigning a reference).
also have a look at the answers to this question:
What is object slicing?
Here's an example: (see http://ideone.com/qeZoa)
#include <iostream>
using namespace std;
struct parent {
virtual const char* hi() const { return "I'm your father..."; }
};
struct child : public parent {
const char* hi() const { return "No way!"; }
};
int main() {
child c;
cout << ((parent) c).hi() << endl;
cout << ((parent&)c).hi() << endl;
}
Yes this is okay . Parent and Child are Polymorphic. as Child inherit's Client you can cast a Child& to Parent&
In expression os << (Parent&)c rhs (Parent&)c is of type Parent& So the operator<<(ostream& os, const Parent& b) will be called from operator<<(ostream& os, const Child& b)
In C++ Polymorphism only works when you have reference or Pointer type
The undesirable result is that the compiler has to create a temporary copy of the Parent portion of the Child object, pass a reference to that temporary to the inserter, and then destroy the temporary. That's a lot of churning...
And, as #NeelBasu hinted, if Parent has virtual functions that are overridden in Child, calls to those functions from the inserter won't call the Child version, because the object passed in is a Parent object.