Am I using copy ctors/move ctors/shared_ptr correctly? Here is my simple example: there is a class A with few primitive members and a class B with few primitive members but also a collection of objects of type A.

This is my A class:

#pragma once

#include&lt;string&gt;

class Hero
{
private:
    long id;
    std::string name;
    int level;
    static long currentId;
public:
    Hero();
    Hero(std::string name, int level);
    Hero(const Hero &amp;hero);
    Hero(Hero &amp;&amp;hero);
    Hero&amp; operator=(const Hero &amp;hero);
    Hero&amp; Hero::operator=(const Hero &amp;&amp;hero);
    long GetId() const { return this-&gt;id; }
    std::string GetName() const { return this-&gt;name; }
    int GetLevel() const { return this-&gt;level; }
    void SetName(const std::string &amp;name);
    void SetLevel(const int &amp;level);
};

#include"Hero.h"

long Hero::currentId = 0;

Hero::Hero(std::string name, int level):name(name), level(level), id(++currentId) 
{

}

Hero::Hero():name(""), level(0), id(++currentId)
{

}

Hero::Hero(const Hero &amp;hero):id(hero.id), name(hero.name), level(hero.level)
{

}

Hero::Hero(Hero &amp;&amp;hero):id(hero.id), name(hero.name), level(hero.level)
{

}

Hero&amp; Hero::operator=(const Hero &amp;hero)
{
    this-&gt;id = hero.id;
    this-&gt;name = hero.name;
    this-&gt;level = hero.level;
    return *this;
}

Hero&amp; Hero::operator=(const Hero &amp;&amp;hero)
{
    this-&gt;id = hero.id;
    this-&gt;name = hero.name;
    this-&gt;level = hero.level;
    return *this;
}

void Hero::SetName(const std::string &amp;name) 
{
    this-&gt;name = name; 
}

void Hero::SetLevel(const int &amp;level) 
{
    this-&gt;level = level; 
}


This is my B class:

#pragma once

#include"Hero.h"
#include&lt;vector&gt;
#include&lt;memory&gt;

class Race
{
private:
    static long currentId;
    long id;
    std::string name;
    std::vector&lt;std::shared_ptr&lt;Hero&gt;&gt; heroes;
    Race(const Race &amp;race); //disable copy constructor
    Race&amp; operator =(const Race &amp;race); //disable assign operator
public:
    Race();
    explicit Race(std::string name);
    std::string GetName() const { return this-&gt;name; }
    void SetName(std::string name);
    void AddHero(Hero &amp;&amp;hero);
    std::vector&lt;std::shared_ptr&lt;Hero&gt;&gt; GetHeroes() const { return heroes; }
};

   #include "Race.h"

long Race::currentId = 0;

Race::Race(std::string name):name(name), heroes(std::vector&lt;std::shared_ptr&lt;Hero&gt;&gt;()), id(++currentId)
{

}

Race::Race():name(""), heroes(std::vector&lt;std::shared_ptr&lt;Hero&gt;&gt;()), id(++currentId)
{

}

void Race::SetName(std::string name)
{
    this-&gt;name=name;
}

void Race::AddHero(Hero &amp;&amp;hero)
{
    heroes.push_back(std::make_shared&lt;Hero&gt;(hero));
}


And this is my main:

#include "stdafx.h"

#include"Race.h"

int _tmain(int argc, _TCHAR* argv[])
{
    Hero elvesHero1("Demon hunter", 8);
    Hero elvesHero2("Warden", 4);
    Race nightElf("Night elf");
    nightElf.AddHero(std::move(elvesHero1));
    nightElf.AddHero(std::move(elvesHero2));
    std::vector&lt;std::shared_ptr&lt;Hero&gt;&gt; heroes=nightElf.GetHeroes();
    return 0;
}


One remark: When the debugger hits nightElf.AddHero(std::move(elvesHero1)); it enters Hero's copy constructor. Shouldn't it go through move constructor?

I just want start on the right foot, so I am waiting for your tips.

LE: If I modify the AddHero method like this:

void Race::AddHero(Hero &amp;&amp;hero)
{
    heroes.push_back(std::make_shared&lt;Hero&gt;(std::move(hero)));
}


it gives the parameter std:move(hero) instead of hero.  It enters move constructor instead of copy constructor.
Firstly, in your header file, you don't need the Hero:: qualification on your move assignment operator. Secondly, you are defining it as Hero&amp; Hero::operator=(const Hero &amp;&amp;hero);. Think about what this is saying - it's saying if you have an rvalue reference to a Hero object, then:


You cannot modify it because it is const
You want to utilize move semantics (specifically, std::move) which will modify the original object and leave it with an empty value.


Hence, your move constructor should always be of the form Hero&amp; Hero::operator=(Hero&amp;&amp; hero). The implementation should also be using std::move:

Hero&amp; operator=(Hero&amp;&amp; hero)
    : id(std::move(hero.id),
      name(std::move(hero.name),
      level(std::move(hero.level)
{ }


For your AddHero methods, a Hero&amp;&amp; hero might be an rvalue reference, but without the std::move for its elements, you're basically saying "take an rvalue reference to Hero, and call copy constructors on each of its elements when you utilize make_shared&lt;Hero&gt;".

Note that moving vs copying for basic types like int or long won't have any performance difference.

That being said, you're doing a lot of work here for no benefit. The rule is, unless you have written a custom destructor, you don't need to write custom copy constructors, copy assignment operators or move assignment operators - the compiler will generate defaults which are correct. It is only when you are managing memory (hence have a delete or delete[] in a destructor somewhere) that you need to implement these.

Finally, a few other small points. Your constructors should be taking strings by const &amp;, ie, explicit Race(const std::string&amp; name). Usage of this-&gt; to return member variables is a bit unidiomatic in C++, likewise in copy constructors and the like, instead of this-&gt;id = hero.id; it's more idiomatic to simply write id = hero.id;. 

I'd suggest reading the Rule of Three post on stackoverflow to get a better understanding of copy construction and copy assignment.