3

I'm relatively new to the more advanced C++ features... So keep that in mind ;)

I have recently defined an Interface to some class, consisting, of course, of only pure virtual functions.

Then, I implemented a specific version of that interface in separate files.

The question is... How do I invoke the specific implementation of that Interface on the user-end side, without revealing the internals of that specific implementation?

So if I have an Interface.h header file that looks like this:

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

Then, a specific Implementation.h header file that looks like this:

class Implementation : public Interface
{
  public:
    Implementation(){};
    virtual ~Implementation(){};
    void InterfaceMethod();
    void ImplementationSpecificMethod();
}

Finally, under main, I have:

int main()
{
  Interface *pInterface = new Implementation();
  // some code
  delete pInterface;
  return 0;
}

How can I do something like this, without revealing the details of Implementation.h, from "main"? Isn't there a way to tell "main"... Hey, "Implementation" is just a type of "Interface"; and keep everything else in a separate library?

I know this must be a duplicate question... But I couldn't find a clear answer to this.

Thanks for the help!

ThermoX
  • 247
  • 2
  • 11
  • 8
    [Factory function](https://en.wikipedia.org/wiki/Factory_(object-oriented_programming)), something like `Interface* MakeInterface() { return new Implementation; }`. Only the function declaration needs to be published in a header, and that by itself doesn't mention `Implementation` – Igor Tandetnik Jun 28 '16 at 14:08
  • @Igor Tandetnik Thanks Igor. If you put that as an answer, I'll mark it down as answered for the credits. – ThermoX Jun 28 '16 at 14:10
  • Do not `delete` things. Go for smart pointers. – SergeyA Jun 28 '16 at 14:12
  • @SergeyA Well... This will be part of my next learning phase... ;) – ThermoX Jun 28 '16 at 14:15

3 Answers3

4

You can use a factory.

Header:

struct Abstract
{
    virtual void foo() = 0;
}

Abstract* create();

Source:

struct Concrete : public Abstract
{
    void foo() { /* code here*/  }
}

Abstract* create()
{
    return new Concrete();
}
Ivan Rubinson
  • 2,468
  • 4
  • 14
  • 33
1

You can hide some of the inner details (privates) of your Implementation class from easy view in the header file by using something like PIMPL to conceal the implementation details in the .cpp file.

See Is the pImpl idiom really used in practice? for more discussion of the pimpl idiom.

Community
  • 1
  • 1
Shadowfen
  • 395
  • 1
  • 8
  • 1
    This doesn't seem to answer the question. The OP is not asking how to hide the implementation details of the derived class. Instead, they are asking how to avoid explicitly instantiating the derived type from the `main` function (i.e., the `main` function is only aware of the interface type and not the derived type). – James Adkison Jun 28 '16 at 14:49
1

Although the factory solution fits better the OP question, I think the PIMPL version can address the same issues too. It is a bit more contrived but avoids the virtual interface:

Header file:

class Interface
{
    struct Implementation;
    std::unique_ptr< Implementation > m_impl;

  public:
    Interface();
    ~Interface();
    void InterfaceMethod();
};

Implementation file:

class Interface::Implementation
{
  public:
    void ImplementationSpecificMethod()
    {
        std::cout << "Bla" << std::endl;
    }
};

Interface::Interface()
    : m_impl( std::make_unique< Interface::Implementation >( ) )
{ }

Interface::~Interface() = default;

void Interface::InterfaceMethod( )
{
    m_impl->ImplementationSpecificMethod();
}

Main file:

int main()
{
    Interface i;
    i.InterfaceMethod(); // prints Bla
}

See it online at repl.it

Tarc
  • 2,966
  • 2
  • 26
  • 38