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.

Source: Windows Questions C++

LEAVE A COMMENT