Outputting member variables when data is spliced c++ - c++

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.

Related

Overloaded operator<< not working good after using virtual function. How to solve this ? It's because of class inheritance/ composition?

I have an issue with my code , something about my virtual function and input/output operator and i don't know how to fix it.
I apologise in advance, this is a long one.
first i created 2 classes ( with inheritance) . Class A and B like this :
class A{
protected:
int x;
public:
A()
{
x=0;
}
A(int x1)
{
x=x1;
}
A(const A &o1)
{
x=o1.x;
}
A &operator=(const A &o1)
{
x=o1.x;
}
friend istream &operator>>(istream &input, A &o1)
{
input >> o1.x;
return input;
}
friend ostream &operator<<(ostream &output, const A &o1)
{
output << o1.x;
return output;
}
virtual void cin2()
{
cin >> *this;
}
friend class C;
};
class B: public A{
protected:
float y;
public:
B(): A()
{
y=0.0;
}
B(int x1, float y1): A(x1)
{
y=y1;
}
B(const B &o2): A(o2)
{
y=o2.y;
}
B &operator=(const B &o2)
{
y=o2.y;
A::operator=(o2);
return *this;
}
friend istream &operator>>(istream &input, B &o2)
{
input >> (A&) o2;
input >> o2.y;
return input;
}
friend ostream &operator<<(ostream &output, const B &o2)
{
output << (A) o2;
output << o2.y;
return output;
}
void cin2()
{
cin >> *this;
}
};
Tested and output & input operators works good in those 2 classes. The virtual method is used below ( explanations there)
Next, i wanted a class that have an object from class A inside of it. I readed about composition and tried to do something similar. Here is the class C:
class C{
protected:
A* obj;
double z;
public:
C()
{
obj=new A;
z=0;
}
C(double z1, const A &obj1)
{
obj=new A(obj1);
z=z1;
}
C(const C &o3)
{
obj=o3.obj;
z=o3.z;
}
C &operator=(const C &o3)
{
obj=o3.obj;
z=o3.z;
return *this;
}
friend istream &operator>>(istream &input, C &o3)
{
input >> o3.z;
B obj2;
o3.obj=&obj2;
o3.obj->cin2();
return input;
}
friend ostream &operator<<(ostream &output, const C &o3)
{
output << o3.z << '\n';
operator<<(output, (B&)o3.obj);
output << '\n';
return output;
}
};
Now here comes the problem.
As i said above, i writed a virtual function and called it here because:
When i read ( cin >>) a class C object, i will automatically read a class A object as well. What i wanted was to go throught class A to his child, class B, and cin (read) both classes parameters from there. ( since class B operator>> is used to cin class A parameters as well).
That worked ( every time i read a class C object it requires me to input values for class A and B parameters as well).
What didn't work was printing what i've just read ( cout << ). I run the code, it's print me class C parameter ( double z) but after that, when it should print the values gived for class A and B parameters, it print some kind of address( i specified that o3.obj is now a class (B&) , and i think it shouldn't do that, though i'm not very sure)
How can i make it works right?
This is main:
int m;
cin >>m;
C* v=new C[m+1];
for(int i=1; i<=m;++i)
cin >> v[i];
cout << '\n';
for(int i=1;i<=m;++i)
cout << v[i];
return 0;
My input:
1 /// numbers of objects
10 /// class C parameter (float z)
11 /// class A parameter (int x)
10.1 /// Class B parameter (float y)
My output:
10 /// value of class C parameter
494590 /// ? some address
Now , you probably think that it was easyer if class C had an object from class B inside ( that way a virtual function is not required because if we use class B input( cin >>), it will automatically read values for class A parameters as well.) Well, it is easyer, but not satisfying what i wanted. Also, i readed about downcasting, dynamic_cast, and probably this is how can i solve this problem in a smart way, but i don't understand exactly where and how to use dynamic_cast.
I will highly appreciate if you can answer me with some exemples as well ( to understand better what to do here).
Probably the answer is very simple and im too dumb to find it myself
Im very excited to find out the answer. If you have the time, please help me out.
I did a re-work of your code to demonstrate what you'd need to do. I stripped out the istream portions, but the principles applied to ostream code are the same. Because operator<<() and operator>>() are not member functions, you can't get polymorhpic behavior from them directly. What you can do is just have them call member functions that do have polymorphic behavior.
The other part that makes this work is a new C constructor that takes a pointer to A as an argument. This allows me to initialize a C object using pointers to A or any child class of A.
You'll also notice I made a lot of other minor changes to the code. I applied a few better practices (default member initialization, complete usage of initialization sections, etc.) and removed unnecessary functions. Copy constructors and assignment operator overloads are not necessary for these classes.
#include <iostream>
#include <memory>
class A {
protected:
int x = 0;
virtual void print(std::ostream &sout) const { sout << x << '\n'; }
public:
A() = default;
A(int x1) : x(x1) {}
virtual ~A() = default;
friend std::ostream &operator<<(std::ostream &output, const A &o1) {
o1.print(output);
return output;
}
};
class B : public A {
protected:
float y = 0.0f;
void print(std::ostream &sout) const override {
sout << y << '\n';
A::print(sout);
}
public:
B() : A() {}
B(int x1, float y1) : A(x1), y(y1) {}
friend std::ostream &operator<<(std::ostream &output, const B &o2) {
o2.print(output);
return output;
}
};
class C {
protected:
double z = 0.0;
std::unique_ptr<A> obj{nullptr};
public:
C() = default;
C(double z1, const A &obj1) : z(z1), obj(new A(obj1)) {}
C(double z1, A *ptrA) : z(z1), obj(ptrA) {} // Newly added
C(const C &o3) : z(o3.z), obj(new A(*(o3.obj))) {}
friend std::ostream &operator<<(std::ostream &output, const C &o3) {
output << o3.z << '\n';
output << *(o3.obj);
return output;
}
};
int main() {
C c(3.14, new B(5, 2.3f));
std::cout << c << '\n';
A a(8);
C c2(4.5, a);
std::cout << c2 << '\n';
return 0;
}
Output:
3.14
2.3
5
4.5
8

how to write a function such that if we print a object then it's need to print a arguments passed in object

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?

Polymorphism does not work with pointers, operator<< overload, inheritance, C++

I have a problem with my code. I have two classes, A and B, and B inherits A. I also have operators << overloaded in both classes.
Everything works, I have no compiler errors, but it seems something is wrong. As far as I understand polymorphism, when I use pointers to base class while creating child class with new, calling a method should match the child class, not the base class.
For the code below,
#include <iostream>
using namespace std;
class A
{
protected:
int a;
public:
A(int aa) : a(aa) {};
virtual void show(ostream& o) const
{
o << "a = " << a << "\n";
}
};
ostream& operator << (ostream& os, const A &o)
{
o.show(os);
return os;
}
class B : public A
{
private:
int b;
public:
B(int bb, int aa) : A(aa), b(bb){}
int getb() const {return b;}
};
ostream & operator << ( ostream & os, const B & o)
{
os << static_cast <const A &>(o);
os << "\n";
os << "b = " << o.getb() << "\n";
return os;
}
int main()
{
A *o1 = new B(2,3);
cout << *o1;
cout << "---------------------\n";
B *o2 = new B(2,3);
cout << *o2;
return 0;
}
In main:
A *o1 = new B(2,3);
cout << *o1;
Shows a = 3, instead of showing a = 3 b = 2 (the call should match the child class, not the base class). The thing is, I need to implement the << and >> operators in every child class, but I think they do not behave as they should.
The output of the program:
Even the modified code with re-implmented show method shows wrong results, it does not show a at all this time:
#include <iostream>
using namespace std;
class A
{
protected:
int a;
public:
A(int aa) : a(aa) {};
virtual void show(ostream& o) const
{
o << "a = " << a << "\n";
}
};
ostream& operator << (ostream& os, const A &o)
{
o.show(os);
return os;
}
class B : public A
{
private:
int b;
public:
B(int bb, int aa) : A(aa), b(bb) {}
int getb() const
{
return b;
}
void show(ostream& o) const
{
o << "b = " << b << "\n";
}
};
ostream & operator << ( ostream & os, const B & o)
{
os << static_cast <const A &>(o);
o.show(os);
return os;
}
int main()
{
A *o1 = new B(2,3);
cout << *o1;
cout << "---------------------\n";
B *o2 = new B(2,3);
cout << *o2;
return 0;
}
enter image description here
you have to implement the virtual function show in derived class B:
class B: public A
{
public:
// some code here
virtual void show(ostream& o) const
{
o << "b = " << b << "\n";
}
};
when I use pointers to base class while creating child class with new,
calling a method should match the child class, not the base class
It does when you call a member function ("method" in some other languages), but operator<< is not a member function – it's an overloaded free function.
When choosing an overload, only the types known at compile-time are used.
Since o1 is an A*, *o1 is an A&, and the overload for A& is chosen.
You're doing this a bit "backwards"; you only need one operator<<, for the base class, which calls the virtual show, and then you override show in the derived classes.
Like this:
class A
{
// ...
virtual void show(ostream& o) const
{
o << "a = " << a << "\n";
}
};
ostream& operator << (ostream& os, const A &o)
{
o.show(os);
return os;
}
class B : public A
{
// ...
void show(ostream& o) const override
{
A::show(o); // Do the "A part".
o << "b = " << b << "\n";
}
};
Follow the same pattern for operator>>.

C++: Using a proxy class to make a member function call in the non proxy class

I am currently working on a class where in a get function, I must return a reference to one of the members. Then, after this member is changed through the = operator, I also want to make a call to one of the classes member functions.
#include <iostream>
class A
{
public:
A() : member(0)
{}
int & get_member()
{
needed_call();
return Aproxy(this);
}
void needed_call()
{
std::cout << "Ran call: " << member << std::endl;
}
private:
int member;
};
class Aproxy
{
friend A;
public:
Aproxy(A * ap): _ap(ap) {}
A & operator=(const int & i)
{
_ap->member = i;
_ap->needed_call();
}
private:
A * _ap;
};
int main(void)
{
A a;
a.get_member() = 5;
}
The problem here is that both classes need the definitions of the other class to perform this task.
If this program worked, it would print out the following
Ran Call: 0
Ran Call: 5
Is there a way to do this? Is this even possible?

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.