1

How can I pass a class derived from an interface to a function taking the interface as a parameter?

I have an interface and a class set up something like this.

class Interface
{
public:
    virtual ~Interface() {}
    virtual void DoStuff() = 0;
};

class MyClass : public Interface
{
public:
    MyClass();
    ~MyClass();
    void DoStuff() override;
};

void TakeAnInterface(std::shared_ptr<Interface> interface);

int main()
{
    auto myInterface = std::make_shared<MyClass>();
    TakeAnInterface(myInterface);
}

The compiler complains about No matching function call to TakeAnInterface(std::shared_ptr<MyClass>&). Why doesn't function TakeAnInterface recieve the Interface class instead of MyClass?

jpo38
  • 20,821
  • 10
  • 70
  • 151
Anders
  • 301
  • 5
  • 12
  • cast from `MyClass` to `Interface` is automatic, while there is no obvious cast from `std::shared_ptr` to `std::shared_ptr` – jpo38 Jan 07 '16 at 09:58
  • This code should compile fine. Which compiler are you using? – Christian Hackl Jan 07 '16 at 10:09
  • And did you post your real code? The error message should only come if you take a reference. Please post **real** code, not something you made up while you typed the question... – Christian Hackl Jan 07 '16 at 10:15

1 Answers1

6

Because myInterface is an instance of std::shared_ptr<MyClass> and not std::shared_ptr<Interface>, and the classes are not automatically convertible to each other.

You can't use std::make_shared, you have to be explicit:

auto myInterface = std::shared_ptr<Interface>(new MyClass);
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Why is it downvoted? – YSC Jan 07 '16 at 10:02
  • Yes, that's it! Thank you :) – Anders Jan 07 '16 at 10:15
  • 2
    shared_ptr that is created like this `auto myInterface = std::shared_ptr(new MyClass);` is not the same as `auto myInterface = std::make_shared();`. First will create pointer to pointer (2 jumps) so it's slower.. Check my solution: `auto myInterface = static_cast>(std::make_shared());`. – Payne Nov 14 '17 at 18:00
  • 2
    @Payne That's an obfuscating and most likely premature optimization if I've ever seen one. Also, the "problem" with my solution isn't about pointer to pointer (double indirection), but rather that there are two memory allocations instead of just one. – Some programmer dude Nov 14 '17 at 18:29