2

What's wrong with my code:

class Game{
    private:
        mtm::Dimensions dimensions;
        std::vector<std::shared_ptr<Character>> board;
};


std::shared_ptr<Character> Game::makeCharacter(CharacterType type, Team team, units_t health,
units_t ammo, units_t range, units_t power) {
    std::shared_ptr<Character> out = nullptr;
    if (type ==SNIPER)
        out=mtm::Sniper(team,health,power,ammo,range);
    return out;
}

I get the following error:

no viable overloaded '='
        out=mtm::Sniper(team,health,power,ammo,range);

Note: Sniper inherits from the abstract class Character.

How may I fix this?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770

1 Answers1

5

You need to use new when constructing the Sniper object, eg:

out = std::shared_ptr<mtm::Sniper>(new mtm::Sniper(team,health,power,ammo,range));

Or better, use std::make_shared() insted:

out = std::make_shared<mtm::Sniper>(team,health,power,ammo,range);

out = mtm::Sniper(...) does not work, because std::shared_ptr<Character> is expecting a Character* pointer to take ownership of (or another std::shared_ptr<T> to share ownership with, where T is convertible to Character). You are constructing a local Sniper object and then trying to assign it to the shared_ptr, but a Sniper object is not implicitly convertible to a Character* pointer, but a Sniper* pointer is (since Sniper derives from Character).

And also, by default std::shared_ptr will delete the pointer it owns (unless you provide a different deleter), so you need to use new (or std::make_shared()) to ensure that object is constructed in dynamic memory that can be delete'd properly. That means new'ing it.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • @Josh Note the bit about `make_shared`. Prefer to use `make_shared` over plain old `new` because with `new` there is a window of vulnerability where the allocation can be leaked. If you use `make_shared`, you're protected end to end (or there's a really freaking nasty bug no one's reported yet) – user4581301 Jun 25 '20 at 23:16
  • @TedLyngmo, intersting read https://stackoverflow.com/q/3899790/6865932 – anastaciu Jun 25 '20 at 23:18
  • @RemyLebeau may you reset the answer to the older version? I'm not allowed to user reset() or make_shared() –  Jun 25 '20 at 23:24
  • 1
    That's a new one. I'm getting used to "No `string`, `vector`, or smart pointers" in Stack Overflow questions, but not "Use smart pointers, but use them wrong." I'd check that requirement with the professor or a TA, because that's just weird. – user4581301 Jun 25 '20 at 23:28
  • @user4581301 May you include some explanation of using these two in your solution, I didn't learn them and don't know what are you doing here, Plus why what I did is wrong? –  Jun 25 '20 at 23:35
  • @Josh: "*may you reset the answer to the older version?*" - no, but I have provided another alternative if you can't use `make_shared()` (why?). – Remy Lebeau Jun 25 '20 at 23:36
  • @Josh wrong may be too strong a word for me to have used, less safe would have been a better choice. Say you `new` the `Sniper`, but before you can place it into the `shared_ptr`, where it becomes managed and safe, something goes wrong. There is now an opportunity for the `Sniper` to get lost and never be freed. `make_shared` closes this window. Sometimes not learning something in the lectures doesn't imply "Do not use" and instead means "Let's see which students read the documentation and usage notes and learned on their own." This is why I recommended checking. – user4581301 Jun 25 '20 at 23:47