How to write assignment operator /copy constructor using object pointers rather than objects?

117 views Asked by At

I see a lot of examples explaining how to write assignment operators/ copy constructors for objects, but, I struggle when it comes to object pointers. An example code is attached.

I would the test2(test1) to invoke the copy constructor, but it does not seem to invoke the user specified copy constructor.

#include <vector>
#include <iostream>
#include <memory>

template <class fd>
class node
{
    public:
//    private:
        std::vector <fd> data_point;
        std::shared_ptr< node <fd> > left;
        std::shared_ptr< node <fd> > right;
        bool collision;

//    public:
        node(std::vector <fd> &data, bool level=0);
        ~node();
        node(const node <fd> &old);
        void check_point();
};

template <class fd>
node <fd>::node(std::vector <fd> &data, bool level)
{
    if (level) throw std::invalid_argument( "Error->Duplicate data" );
    else
    {
        data_point = data;
        left = nullptr;
        right = nullptr;
        collision = level;
    }
}

template <class fd>
node <fd>::~node() {}

template <class fd>
node <fd>::node(const node <fd> &old)
{
    std::cout<<"Copy constructor called"<<std::endl;
//    this->data_point = old.data_point;
//    this->left = new node <fd> (old.left);
//    this->right = new node <fd> (old.right);
//    this->collision = old.collision;
}

template <class fd>
void node <fd>::check_point()
{
    if (this == nullptr)
    {
        std::cout<<"It's a leaf node with None"<<std::endl;
    }
    else
    {
        for (int dim=0; dim<this->data_point.size(); dim++)
        {
            std::cout<<data_point[dim]<<" ";
        }
        std::cout<<std::endl;
    }
}

int main()
{
    std::vector <double> data;
    data = {50};
    std::shared_ptr <node <double> > test1 = std::make_shared <node <double> > (data);
//    std::cout << typeid(test1).name() << std::endl;
    test1->check_point();//Prints 50.Expected
    std::shared_ptr <node <double> > test2(test1);//Expecting copyconstructor call for deep copy
    test1->data_point = {75};//Changing value
    test2->check_point();//If deep copy happened, value would not change. Default copy constructor does not shallow copy and hence value does not change.
    test1->check_point();
    return 0;
}

It would be great if you could explain how this is to be done.

1

There are 1 answers

5
wally On BEST ANSWER

Minimal change to trigger the use of the copy constructor in the above program:

//std::shared_ptr <node <double> > test2(test1);//Expecting copyconstructor call for deep copy
std::shared_ptr <node <double> > test2 = std::make_shared <node <double> >(*test1);

The new line will dereference the pointer of test1 and pass it to the constructor constructing test2 thereby invoking the copy constructor.

New output:

50
Copy constructor called

75