0

I want to make an operator= and copy constructor, to be called in the inherited class.

For normal objects, it works fine, but when I'm trying to call, for example, operator= with a pointer, it is just copying the object address.

So my question is, how can I call those methods with pointers?

#include <iostream>

// base class
class a {     
public:
    //constructors
    a(): x(0), y(1), z(0){ std::cout << "no parameter constructor A\n"; }
    a(int a, int b, int c) :x(a), y(b), z(c){ std::cout << "parameter constructor A\n"; }
    a(const a& ob):x(ob.x), y(ob.y), z(ob.z)
    {
        std::cout << "copy constructor A\n";
    }
    //operator
    a& operator=(const a& obj) 
    {
        if (this != &obj)
        {
            x = obj.x;
            y = obj.y;
            z = obj.z;
        }
        std::cout << "operator = A\n";
        return *this;   
    }
protected:
    int x, y, z;
};

//child class
class b : public a
{
public:
    //constructors
    b() : p(0){ std::cout << "no parameter constructor B\n"; }
    b(int X, int Y, int Z, int B) : a(X, Y, Z), p(B) { std::cout << "parameter constructor B\n"; }
    b(const b& obj) :p(obj.p), a(obj)
    {
        std::cout << "copy constructor B\n";
    }
    //operator =
    b& operator=(const b &obj)
    {
        if (this != &obj)
        {
            p = obj.p;
            &a::operator=(obj);
        }
        std::cout << "operator = B\n";
            return *this;
    }
private:
    int p;
};

int main()
{
    b obj0(4, 8, 16, 32);
    b obj1(obj0);   // copy constructor
    b obj2;
    obj2 = obj1;    // operator =
    std::cout << std::endl << std::endl;
    std::cout << "for pointers:\n\n";
    a* obj3 = new b(4, 8, 16, 32);
    a* obj4(obj3);
    obj4 = obj3;
    return 0;
}

output

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Bolo
  • 17
  • 2
  • You'll need a constructor that accepts a pointer. – tadman Feb 09 '21 at 22:49
  • It's not shown here, but if you dealing with polymorphism, see: https://stackoverflow.com/questions/5148706/copying-a-polymorphic-object-in-c – NathanOliver Feb 09 '21 at 22:51
  • 2
    Pointers are just addresses. You're calling `operator=` on the _pointers_, not on the objects pointed at. And it is indeed, copying the pointer. Copying a pointer will not copy the object pointed at. Not even the standard smart pointers do that. I suppose a custom polymorphic_pointer could. – Mooing Duck Feb 09 '21 at 23:01
  • I tried to make http://coliru.stacked-crooked.com/a/b545240219c77c8d to handle polymorphic cases like this, but I have an error somewhere :( – Mooing Duck Feb 09 '21 at 23:02
  • I got it to compile! http://coliru.stacked-crooked.com/a/e1c6eeae7de20f7f – Mooing Duck Feb 12 '21 at 18:13

1 Answers1

2

One of the purposes of using pointers (or references) is to avoid needing to create a copy of the object. Passing a pointer to the object allows the receiver to refer to and manipulate on the original object.

If you wish the pointer to receive a new object, then you would use new.

When dealing with polymorphism as in your example, you would probably need a virtual method that creates a proper clone (sometimes called a deep copy).

class a {
    //...
    virtual a * clone () const = 0;
};

class b : public a {
    //...
    b * clone () const {
        return new b(*this);
    }
};

//...
    a *obj4 = obj3->clone();
//...

We leverage that b * is a covariant return type for a *, so that b::clone() can return a b *, but a::clone() can use the b::clone() as an override and still return an a *.

jxh
  • 69,070
  • 8
  • 110
  • 193
  • Good place to use "covariant return type"... `b:::clone()` should return `b*` not `a*`. Furthermore, `clone()` should be `const`. – Ben Voigt Feb 09 '21 at 23:12