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.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
#include<iostream>
using namespace std;
class player{
private:
string name;
int health;
int xp;
public:
void names (string get_name, int get_health, int get_xp){
name=get_name;
health=get_health;
xp=get_xp;
}
};
int main(){
player p;
p.names("Mohit",100,3);
cout<<p.health<<endl;
cout<<p.xp<<endl;
cout<<p.name<<endl;
player *hero = new player();
hero ->names("Tavishi",1000,3);
cout<<(*hero).name<<endl;
cout<<(*hero).xp<<endl;
cout<<(*hero).health<<endl;
delete hero;
return 0;
}
I am accessing the attributes within the class only, then why am I getting the error regarding the private access specifier??
Here's your code, fixed up a bit:
#include <iostream>
#include <string> // Include what you use
class player {
private:
std::string name;
int health;
int xp;
public:
void names(std::string get_name, int get_health, int get_xp) {
name = get_name;
health = get_health;
xp = get_xp;
}
// Simplest fix: Getters
std::string get_name() const { return name; }
int get_health() const { return health; }
int get_xp() const { return xp; }
};
int main() {
player p;
p.names("Mohit", 100, 3);
// cout<<p.health<<endl; // Not "within the class"
// cout<<p.xp<<endl; // Not "within the class"
// cout<<p.name<<endl; // Not "within the class"
std::cout << p.get_health() << '\n'
<< p.get_xp() << '\n'
<< p.get_name() << '\n';
player *hero = new player();
hero->names("Tavishi", 1000, 3);
std::cout << hero->get_name() << '\n'; // Prefer arrow operator over (*).
std::cout << hero->get_xp() << '\n';
std::cout << hero->get_health() << '\n';
delete hero;
return 0;
}
You were using an object in the main() function, which is not "within the class" to attempt to access private members. When people say that you can use private members directly "within the class" they mean from within a class member function. Anything else is considered "out of the class" and the private/public restrictions are enforced.
If you need access to them, you can provide getter functions in your class, which is what I did.
Here's your code again, this time better utilizing C++. Namely, constructors and operator overloading.
#include <iostream>
#include <memory>
#include <string> // Include what you use
class player {
private:
std::string name{}; // Default member initialization makes default ctor
int health = 0; // easy to implement
int xp = 0;
public:
// Provide constructors for easier initialization
player() = default;
player(std::string name, int health, int xp)
: name(name), health(health), xp(xp) {}
// void names(std::string get_name, int get_health, int get_xp) {
// name = get_name;
// health = get_health;
// xp = get_xp;
// }
// Simplest fix: Getters
// ** Getter may not be necessary anymore if your only purpose is printing
std::string get_name() const { return name; }
int get_health() const { return health; }
int get_xp() const { return xp; }
// If you want to cout object directly, provide operator<<()
// Friends can access private members directly; they are **not** class members
friend std::ostream& operator<<(std::ostream& sout, const player& p) {
return sout << p.health << '\n' << p.xp << '\n' << p.name << '\n';
}
};
int main() {
player p{"Mohit", 100, 3}; // Much simpler initialization
// cout<<p.health<<endl; // Not "within the class"
// cout<<p.xp<<endl; // Not "within the class"
// cout<<p.name<<endl; // Not "within the class"
std::cout << p; // Simpler way to print
auto hero =
std::make_unique<player>("Tavishi", 1000, 3); // Smart pointer
// no need to delete
std::cout << *hero;
return 0;
}
In the class base, we need to write a function such that printing an object will print arguments of an object using oops concept.
#include <iostream>
using namespace std;
class base{
int num;
string s;
public:
base(int elem,string p){
cout<<elem<<" "<<p<<endl;
}
// todo:
};
int main() {
base obj(12,"shivam");
// cout<<obj<<endl;
}
Your current idea is not far from working, except you print the constructor arguments to std::cout as soon as an instance of base is created - not when the programmer using the class expresses such a wish. What you need to do is to save the arguments given when constructing a base. You'll then be able to print them on demand.
Example:
#include <iostream>
#include <string>
class base {
public:
base(int n, const std::string& str) : // save the arguments given using
num(n), s(str) // <- the member initializer list
{
// empty constructor body
}
// declare a friend function with special privileges to read private
// member variables and call private functions:
friend std::ostream& operator<<(std::ostream&, const base&);
private:
int num;
std::string s;
};
// define the free (friend) function with access to private base members:
std::ostream& operator<<(std::ostream& os, const base& b) {
// here you format the output as you'd like:
return os << '{' << b.num << ',' << b.s << '}';
}
int main() {
base obj(12,"shivam");
std::cout << obj << '\n';
}
Output:
{12,shivam}
Try this:
int IntS(int y)
{
return y;
}
class base{
public:
base(int enume, std::string str)
{
std::cout << IntS(enume) << '\n';
std::cout << str << '\n;
}
};
int main()
{
base mybase(IntS(5), "five");
return 0;
}
See also, std::map:
How can I print out C++ map values?
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.
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;
}
Hello I currently face a problem were I want to output data from 2 separate classes, one is a base class and one is a derived class, I want to overload the << operator to output all the data at once but seem to have trouble doing so, I have something like this:
#include <iostream>
using namespace std;
class A
{
char* A;
char* B;
public:
A() {A = ' '; B = ' ';}
A(char* pLast, char* pFirst)
{
A = new char [strlen(pLast) + 1];
B = new char [strlen(pFirst) + 1];
strcpy(A,pLast);
strcpy(B,pFirst);
};
}
class C:public A
{
int X;
char Y;
int Z;
public:
C(char* A, char* B, int X, char Y, int Z)
:A(A,B)
{
//do stuff here
}
friend std::ostream& operator<<(std::ostream& out, const C& outPut)
{
out << outPut.A << "," << outPut.B << "," <<outPut.X<< "," << outPut.Y << "," << outPut.Z << endl;
return out;
}
};
When I try to run this it tells me A and B are out of range which makes sense since those members are private in class A, I don't know how to get around this. I tried creating getter methods to access A and B but the data comes out as blank. I even tried added an object of class A as a member of class B to try to allow access to the members in class B still the data comes out blank. How do I get around this problem?
There are several ways of dealing with this. One way obviously is to make the members of A protected rather than private. A derived class B can then access them.
Another way indeed are getter functions. The fact they didn't work for you is related to problems in your constructors and other problems in your code. But public getters also have the disadvantage of enabling anyone (not just derived classes) to get access to the values of your data members.
Here is a third approach, which I believe makes sense in your case: Define a separate operator<< in A, and make use of that operator when you define the one for B:
#include <cstring>
#include <iostream>
using namespace std;
class A
{
char* _a;
char* _b;
public:
A()
: _a(),_b()
{ }
A(const char *pLast, const char *pFirst)
: _a(new char [std::strlen(pLast)]),
_b(new char [std::strlen(pFirst)])
{
strcpy(_a,pLast);
strcpy(_b,pFirst);
}
friend std::ostream& operator<<(std::ostream& out, const A& obj)
{
out << obj._a << "," << obj._b;
return out;
}
};
class B : public A
{
int _x;
char _y;
int _z;
public:
B(const char *pLast, const char *pFirst, int x, char y, int z)
: A(pLast,pFirst),
_x(x),_y(y),_z(z)
{ }
friend std::ostream& operator<<(std::ostream& out, const B& obj)
{
out << static_cast<const A&>(obj) << ','
<< obj._x << ','
<< obj._y << ','
<< obj._z;
return out;
}
};
int main()
{
B b("hello","world",1,'a',3);
std::cout << b << std::endl;
return 0;
}
I've also corrected the other problems I found, so the above actually works.