user10005002
user10005002

Reputation: 33

How do you make a copy constructor/assignment operator for a class that contains a shared_ptr? C++

Say, I have a class .h file named Ninja

I have two member functions and the default name is set to Ninja master and discple_ child is set to nullptr

Below is a snippit of the public/private of my class:

private:

    std::string name_;
    std::shared_ptr<Ninja> disciples_;


  public:
    Ninja(std::string name = "Ninja Master")
      : name_{name},
        disciples_{std::shared_ptr<Ninja>(nullptr)}
     {}
    ~Ninja() = default;     
Ninja(const Ninja& copy2);  //trying to make a copy constructor here
Ninja& operator=(const Ninja&);   // I also need help creating an assignment operator too 

I want to make a deep copy constructor but I am getting errors.

Below is the snippet for my deep copy constructor in the .cpp file.

Ninja::Ninja(const Ninja& copy2) {
   Ninja a();
   a = copy2; //error cannot convert const Ninja to Ninja() in assignment
}

Upvotes: 0

Views: 322

Answers (3)

Sid S
Sid S

Reputation: 6125

Ninja a(); declares a function.

If you want to create a Ninja object, drop the parentheses : Ninja a;


The copy constructor could be implemented like this:

Ninja::Ninja(const Ninja &n)
:   name_(n.name_),
    disciples_(n.disciples_)
{
}

Upvotes: 1

Evg
Evg

Reputation: 26292

An example of a deep copy constructor:

Ninja(const Ninja& other) 
    : name_(other.name_), 
      disciples_(other.disciples_ ? 
          std::make_shared<Ninja>(*other.disciples_) : 
          std::shared_ptr<Ninja>{}
      )
{}

It will create a new shared_ptr that will hold a copy of Ninja object managed by other.disciples_.

If you don't need a deep copy, just omit the copy constuctor. It will be implicitly defined and will make a copy of shared_ptr automatically.

I don't understand the usage of the ? ternary operator. Please explain.

We first check that shared_ptr stores a non-null pointer. If it does, we dereference it and create a new one using the copy constructor of Ninja, if it doesn't, we create an empty shared_ptr. If disciples_ is never empty by design, this check can be omitted.

Upvotes: 0

Shrikant
Shrikant

Reputation: 774

You can do something like below -

  if( copy2.disciples_ )
    {   
        this->disciples_ = make_shared<Ninja>();
        this->disciples_->name_ = copy2.disciples_->name_;
        this->disciples_->disciples_= copy2.disciples_->disciples_;
    }   
    else
    {   
        this->disciples_ = copy2.disciples_;
    }   

Upvotes: 0

Related Questions