using overloaded << operator in another << overload in a different class - c++

So here's the problem. I have a class B where I have overloaded the << operator and a class A where the << operator is also overloaded. However, the << overload in class B doesn't seem to be working in the << overload in class A. It simply returns the address of b as if the << overload in class B doesn't exist.
Any help would be very appreciated
#pragma once
#include <ostream>
using namespace std;
class B {
public:
B(int x) {
this->x = x;
}
friend ostream& operator<<(ostream& os, B& b)
{
os << "this is B " << b.x;
return os;
}
private:
int x;
};
#pragma once
#include <ostream>
#include "B.h"
using namespace std;
class A {
public:
A(B* b) {
this->b = b;
this->x = 0;
}
friend ostream& operator<<(ostream& os, A& a)
{
os << a.b << endl; //this doesnt work <============
os << "this is a " << a.x;
return os;
}
private:
int x;
B* b;
};
#include <iostream>
#include "A.h"
#include "B.h"
using namespace std;
int main()
{
B* b = new B(1);
A* a = new A(b);
cout << *a << "inside a "<< endl;
cout << *b << "inside b " <<endl;
}

os << a.b // ...
a.b is not a B, for which you defined an overload, look closer at your code:
class A {
private:
B* b;
};
That's a B *, and not a B, and no overload exists for that.
If you want to call the overload here, use os << (*a.b) // ...;

Related

2 way friendship and between classes and it's solution as forward declaration

I wanted to know if there's any exsisting solution to the problem:
class b;
class a {
int x;
public:
friend class b;
a() { x = 5 }
void print(b obj) {
cout << x << endl;
cout << obj.y << endl;
}
};
class b {
int y;
public:
friend class a;
b() { y = 10 }
void print(a obj) {
cout << y << endl;
cout << obj.x << endl;
}
};
"This is giving me an issue since class b body is not define before class a, so what is there any easy and existing way to make it work?
For starters you forgot to place a semicolon after these statements
x = 5
and
y = 10
You can define member functions that access data members of other class when the other class is defined that is when it is a complete type.
So place the definition of the function print of the class a after the definition of the class b.
For example
#include <iostream>
using namespace std;
class b;
class a {
int x;
public:
friend class b;
a() { x = 5; }
/* inline */ void print(b obj);
};
class b {
int y;
public:
friend class a;
b() { y = 10; }
void print(a obj) {
cout << y << endl;
cout << obj.x << endl;
}
};
void a::print(b obj) {
cout << x << endl;
cout << obj.y << endl;
}
int main()
{
a a;
a.print( b() );
b b;
b.print( ::a() );
return 0;
}
The program output is
5
10
10
5
You could place the class definitions with member function declarations in a header and then define the member functions in a cpp file.

overloading << operator whilst accessing private elements (friend)

I'm writing a program that requires me to overload the << operator whilst accessing private members of the class. It goes like this:
A.h
#pragma once
#include <ostream>
#include "B.h"
using namespace std;
class A {
public:
A(B* b) {
this->b = b;
this->x = 0;
}
friend ostream& operator<<(ostream& os, A& a)
{
os << "this is a " << a.x;
return os;
}
private:
int x;
B* b;
};
B.h
#pragma once
#include <ostream>
using namespace std;
class B {
public:
B(int x) {
this->x = x;
}
friend ostream& operator<<(ostream& os, B& b)
{
os << "this is B " << b.x;
return os;
}
private:
int x;
};
main.cpp
#include <iostream>
#include "A.h"
#include "B.h"
using namespace std;
int main()
{
B* b = new B(1);
A* a = new A(b);
cout << a << endl;
cout << b << endl;
}
However, this doesn't print a and b, just the memory address of the two objects. I think it has something to do with the order of operations, but I'm not sure on that.
Also, I can't use ostream& operator<<() as an independent function since that would prevent me from accessing the private member of the class.
I could potentially implement a void print() inside the class and use that to print the private members, but I don't think that's what my professor has in mind (considering there's already a void print() implemented for something else).
In main(), a and b are pointers. This code:
cout << a
cout << b
Is effectively calling this:
cout.operator<<(a)
cout.operator<<(b)
Because std::ostream has a member operator<<(void*) for printing a pointer, and all pointers are implicitly convertible to void*. This is why you are seeing memory addresses in the output. Your custom operators are not being called at all, as they require you to pass actual object instances to operator<<, which you are not doing.
You need to dereference your pointers in main(), eg:
#include <iostream>
#include "A.h"
#include "B.h"
using namespace std;
int main()
{
B* b = new B(1);
A* a = new A(b);
cout << *a << endl;
cout << *b << endl;
delete a;
delete b;
}
In this code:
cout << *a
cout << *b
Since std::ostream does not have member operator<<s for A or B, this will effectively call this instead:
operator<<(cout, *a)
operator<<(cout, *b)
Which will call your custom operators.
Otherwise, simply get rid of the pointers altogether:
#include <iostream>
#include "A.h"
#include "B.h"
using namespace std;
int main()
{
B b(1);
A a(&b);
cout << a << endl;
cout << b << endl;
}
Which will also effectively call this:
operator<<(cout, a)
operator<<(cout, b)
Thus calling your custom operators.
On a side note, your custom operators should be accepting references to const A+B objects, eg:
friend ostream& operator<<(ostream& os, const A& a)
friend ostream& operator<<(ostream& os, const B& b)

Why I can use the class name as a function name?

As far as I know in C++ we cannot use the same identifier for another declaration:
int x;
char x; // compile-time error: redefinition.
But here is an example where I was messing with classes:
#include "stdafx.h"
#include <iostream>
#include <vector>
class A {
public:
A(int);
void print()const;
friend std::ostream& operator << (std::ostream& out, A& rhs);
private:
int value1;
};
std::ostream& operator << (std::ostream& out, A& rhs) {
out << "rhs.value1 = " << rhs.value1 << std::endl;
return out;
}
A::A(int x) : value1(x) { std::cout << "ctor A(x)" << std::endl; }
void A::print()const {
std::cout << "value1: " << value1 << std::endl;
}
int A(int x) {
std::cout << "inside A(int x)" << std::endl;
return x;
}
int main(){
class A a { 0 };
a = A(7);
a.print();
std::cout << A(7) << std::endl;
std::cout << A(5) << std::endl; // here if I comment out the function a it is ok as long as I overloaded the insertion operator
// and if I add the function A it hides the insertion operator!
std::cout << std::endl;
std::cin.get();
return 0;
}
So as you can see above I must add the keyword class whenever I declare an object of class Aotherwise I get a compile-time error. Why?
Is the expression a = A(7); a function call and the return value is passed to the constructor of class A that takes an integer. Or simply no function call but only ctor call?
From my point of view, you have a class A and a function A, so you have to point out A is a class or a function that's why you have to add "class" when you declare an object of A.
According to the following code, two classes, A and B, are defined, they are exactly same, but A can be a function or a class, so when you declare a object A, you have to add a "class" before A, while declare a object of B is no need to add a "class"
For the second question, first function A is called, and its return value is used to construct object a. You can see first x=7 is in the function A, and ctor x=8 because the function return x+1.
The output:
ctor A(x) x=0
inside A(int x) x=7
ctor A(x) x=8
ctor B(x)
The test code:
#include <iostream>
#include <vector>
class A {
public:
A(int);
private:
int value1;
};
class B {
public:
B(int);
private:
int value1;
};
B::B(int x) : value1(x) { std::cout << "ctor B(x)" << std::endl; }
A::A(int x) : value1(x) { std::cout << "ctor A(x) x=" << x <<std::endl; }
int A(int x) {
std::cout << "inside A(int x) x=" << x << std::endl;
x=x+1;
return x;
}
int main(){
class A a(0);
a = A(7);
B b(0);
return 0;
}

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++ operator overloading in abstract class

Let's say we have the following scenario:
We have a base abstract class A. Then we have classes B and C which derived from A. We also have class D which is a custom implementation of a std::vector<T> - it contains a private property list of type std::vector<T> and some custom methods to work with it.
Now my problem is as follows: I would like to overload the operator + in class A to be able to do this:
B* b = new B();
C* c = new C();
D mList = b+c; //the property *list* of mList would contain b an c
I have tried everything and can't seem to be able to get it to work and am out of ideas. Is it even possible to override an operator in a base abstract class so that it will apply to derived classes?
EDIT:
Here is what I have tried so far:
File A.h:
#pragma once
#include <string>
#include <iostream>
using namespace std;
class A
{
protected:
double price;
string name;
public:
A() :name(""){};
A(string n, double p){
price = p;
name = n;
};
~A(){};
virtual void calculate(double value) = 0;
virtual void print() const = 0;
};
File B.h:
#pragma once
#include "A.h"
class B : public A
{
private:
public:
B() :A(){};
B(string n, double p) :A(n,p){};
~B();
void calculate(double value)
{
price = price + value;
}
void print() const
{
cout << name << " says: " << " " << price;
}
};
File C.h:
#include "A.h"
class C : public A
{
private:
public:
C() :A(){};
C(string n, double p) : A(n,p){};
~C();
void calculate(double value)
{
price = price * value;
}
void print() const
{
cout << name << " says: " << " " << price;
}
};
File D.H:
#include <vector>
class D
{
private:
vector<A*> list;
public:
D(){}
~D()
{
int len = list.size();
for (int i = 0; i < len; i++)
{
delete list[i];
}
};
void push(A* item)
{
list.push_back(item);
}
A* pop()
{
A* last = list.back();
list.pop_back();
return last;
}
//I have tried overriding it here and in A.h
friend D D::operator+(A* first, A* second)
{
D temp;
temp.push(first);
temp.push(second);
return temp;
}
};
It looks like you're are adding two pointers, so A::operator+() won't even be called. But to answer your question, yes, operator overloading is inheritable. Even from an abstract base class.
class A
{
public:
virtual void test() = 0;
int operator+(const A &a) {return 42;}
};
class B : public A
{
void test() {};
};
class C : public A
{
void test() {};
};
int main()
{
B* b = new B();
C* c = new C();
cout << "result: " << *b + *c << endl;
return 0;
}
Output:
result: 42
When c in C* and d is a D* if you write c+d you're just adding pointers, whatever overloads you defined.
Maybe you could redefine pointer addition for A* with a global operator(A*, A*) (not sure it's possible) but it would be quite dangerous for users since it overrides standard behavior.
The better solution is to define operators on references (const) and not pointers, which in your case is a little less convenient since you'd have to write: list = *c + *d;
Also, since you're using containers of pointers for polymorphism, I strongly recommend using shared_ptr.
Working code below (simplified, but with the ability to add more than 2 elements):
#include <list>
using std::list;
struct A {
list<const A*> operator+(const A& right) { // A + A
list<const A*> r;
r.push_back(this);
r.push_back(&right);
return r;
}
list<const A*> operator+(const list<const A*> & right) { // A + list
list<const A*> r = right;
r.push_front(this);
return r;
}
virtual void print() const = 0;
};
list<const A*> operator+(const list<const A*> & left, const A & right) { // list + A
list<const A*> r = left;
r.push_back(&right);
return r;
}
#include <iostream>
struct B : A {
void print() const { std::cout << "B" << std::endl; }
};
struct C : A {
void print() const { std::cout << "C" << std::endl; }
};
int main() {
B b;
C c;
B* pb = new B;
list<const A*> lst = b + c + *pb;
for(list<const A*>::iterator i = lst.begin(); i != lst.end(); ++i) {
(*i)->print();
}
return 0;
}
Take a look at this code-example:
#include <iostream>
class B;
class A;
class A
{
public:
virtual void overrideProp() = 0;
friend int operator+(const B& b, const A& a);
friend std::ostream& operator<<(std::ostream& os, const A& a)
{
return os << a.prop;
}
protected:
int prop;
};
class B : public A
{
public:
B(){overrideProp();}
void overrideProp(){prop=1;}
};
class C : public A
{
public:
C(){overrideProp();}
void overrideProp(){prop=3;}
};
int operator+(const B& b, const A& a)
{
return b.prop + a.prop;
}
class D
{
public:
void operator=(const int& i){d = i;}
friend std::ostream& operator<<(std::ostream& os, const D& a)
{
return os << a.d;
}
private:
int d;
};
int main()
{
B b;
C c;
D d; d = b+c;
std::cout << "B contains: " << b << " C contains: " << c << " D contains: " << d;
}
The output is B contains: 1 C contains: 3 D contains: 4
Here's an compilable and runnable example (http://codepad.org/cQU2VHMp) I wrote before you clarified the question, maybe it helps. The idea is that the addition overload can either be unary (and D defined as a friend), as here, or defined as a non-member binary operator using public methods. Note that I have to dereference the pointers b and c to make this work, as adding pointers often don't make sense.
#include <iostream>
#include <string>
class D {
public:
void Foo() {
std::cout << "D: " << member_ << std::endl;
}
friend class A;
private:
std::string member_;
};
class A {
public:
virtual void Foo() = 0;
A(const std::string &member) : member_(member) {}
D operator+(const A &rhs) {
D out;
out.member_ = member_ + " " + rhs.member_;
return out; // Uses the default copy constructor of D
}
protected:
std::string member_;
};
class B : public A {
public:
B(const std::string &member) : A(member) {}
void Foo() {
std::cout << "B: " << member_ << std::endl;
}
};
class C : public A {
public:
C(const std::string &member) : A(member) {}
void Foo() {
std::cout << "C: " << member_ << std::endl;
}
};
int main() {
B *b = new B("hello");
C *c = new C("world");
b->Foo();
c->Foo();
D d = (*b) + (*c);
d.Foo();
delete b;
delete c;
return 0;
}
The output of this program is:
B: hello
C: world
D: hello world